I am building a hot and Cold App in JS and jQuery.
My issue is on form submit that user input inserts a number and the game tells them if its hold or cold or hotter or holder based on how close or far from the number.
Issue is that It only works the first time. After that it does nothing.
How do I made it so that when the user input on submit it generates a new secretNumber and based on the checker I have setup outputs either hot or cold or hotter or colder.
Seems its not generating a new secret number or it is just not inputing it.
Code here http://codepen.io/mackenzieabby/pen/qOXNLg
JS
$(document).ready(function(){
// Global Variables.
var theSecret = Math.floor((Math.random() * 100) + 0); // Creates Secret Number
var userGuess = $('#userGuess').val(); // User Inut Guess
var count = 0;
var addList = document.createElement("li")
// Display information modal box
$(".what").click(function(){
$(".overlay").fadeIn(1000);
});
// Hide information modal box
$("a.close").click(function(){
$(".overlay").fadeOut(1000);
});
// Functions
// New Game
function newGame() {
// new gama data here
}
// Add To List
function addtoList() {
}
function preventRefresh() {
$("form").submit(function(event) {
event.preventDefault();
theSecret();
veryHotGuess();
hotGuess();
veryColdGuess();
coldGuess()
correctAnswer();
});
}
preventRefresh();
function addGuess() {
$("ul#guessList").append("<li>" + userGuess + "</li>");
}
// Checks if hot or cold or correct
function veryHotGuess() {
if (userGuess < 25 && theSecret < 25) {
document.getElementById('feedback').innerHTML = "Very Hot";
}
}
function hotGuess() {
if (userGuess < 50 && theSecret < 50) {
document.getElementById('feedback').innerHTML = "Hot";
}
}
function veryColdGuess() {
if (userGuess < 100 && theSecret < 100) {
document.getElementById('feedback').innerHTML = "Very Cold";
}
}
function coldGuess() {
if (userGuess < 75 && theSecret < 75) {
document.getElementById('feedback').innerHTML = "Cold";
}
}
function correctAnswer() {
if (userGuess == theSecret) {
document.getElementById('feedback').innerHTML = "You Got It";
}
}
});
Calling theSecret(); causes a JavaScript error. You are calling the variable as a function, which it isn’t obviously.
BTW, I think your calculation of guess "temperature" might be quite wrong.
You have to redefine your definition of Global variable in javascript:
$(document).ready(function(){
// Global Variables.
var theSecret = Math.floor((Math.random() * 100) + 0); // Creates Secret Number
var userGuess = $('#userGuess').val(); // User Inut Guess
var count = 0;
var addList = document.createElement("li")
...
those ARE NOT global variables, because you made then in a scope, the document.ready scope... a Global Variable must be defined outside any scope, so it's available in all scopes, including inside the document.ready as well inside any function method you wrote.
Secondly, you need to rethink what you are doing, as a rule, you are repeating yourself over and over with
document.getElementById('feedback').innerHTML = xxxx;
one day you need to change the feedback to something else, or also write something else, can you see in how many places you need to change your code? When you see several lines of almost the same code: You're doing it wrong...
And you need to simplify your calculations, you make it hard to code and see what's going on...
Third, as Alexander pointed out, you need to re-think how you're calculating, what you want to calculate if not the userGuess or the theSecret, but give an answer based on how close/far the user guess is from the correct value ... that I would call it the difference between 2 numbers.
something like: Math.abs(theSecret - userGuess)
Here's my approach:
http://codepen.io/anon/pen/wKqzvg?editors=001
(irrelevant code removed)
var theSecret = 0,
guesses = [];
$(document).ready(function() {
// Creates Secret Number
theSecret = Math.floor((Math.random() * 100) + 0);
$("form").submit(function(evt) {
evt.preventDefault();
checkTemperature();
});
});
// Functions
// Add To List
function addToList(txt) {
guesses.push(txt);
$("#count").text(guesses.length);
$("ul#guessList").append("<li>" + txt + "</li>");
}
function write(txt) {
document.getElementById('feedback').innerHTML = txt;
}
function checkTemperature() {
var userGuess = parseInt($('#userGuess').val()),
dif = Math.abs(theSecret - userGuess);
// for debug only
console.log("theSecret:" + theSecret);
console.log("userGuess:" + userGuess);
console.log("dif:" + dif);
addToList(userGuess);
if (dif < 5)
write("Vulcan Hot");
else if (dif < 25)
write("Very Hot");
else if (dif < 50)
write("Hot");
else if (dif < 75)
write("Cold");
else if (dif < 100)
write("Very Cold");
else if (dif === 0)
write("You Got It");
}
The problem isn't with theSecret but with userGuess. You were not grabbing the value on submit so it was empty. I suggest to always console.log or inspect variables to make sure they are getting populated correctly. In your submit I added this: userGuess = $('#userGuess').val(); and it will now check correctly.
However, as Alexander mentioned the math is wrong. The value will always be under 100 and so it will always be Very Cold. You have to get the absolute difference of both numbers and then do your guess check:
var difference = Math.abs(theSecret - userGuess);
if (difference < 100) {
document.getElementById('feedback').innerHTML = "Very Cold";
}
if (difference < 75) {
document.getElementById('feedback').innerHTML = "Cold";
}
if (difference < 50) {
document.getElementById('feedback').innerHTML = "Hot";
}
if (difference < 25) {
document.getElementById('feedback').innerHTML = "Very Hot";
}
if (difference == 0) {
document.getElementById('feedback').innerHTML = "You Got It";
}
I forked your project here: http://codepen.io/paulmg/pen/xwLExM
Related
I am trying to learn javascript, I am playing with a game that picks a random number.
I would like to have 2 functions, random and guess. Random generates a new number between 1-10. Guess is where it checks if the number was guessed, if not re-runs the random function and generates a new number to try.
var x;
function random(){
let x = Math.floor((Math.random() * 10) + 1);
guess();
}
function guess(x){
if(x === 3){
alert('you are correct!');
}else{
alert('try again');
random();
}
}
random();
This just alerts try again every time, i'm guessing because it's not generating a new number each time the function is called?
How can you create the random function so it generates a new number each time its called?
***** Correction, it appears to generate a new number but x is undefined within the guess function**
The x in the guess() is the x that gets passed to it as a parameter. I would remove the var x; declaration and pass a value when calling like guess(x)
function random(){
const x = Math.floor((Math.random() * 10) + 1);
guess(x);
}
function guess(x){
if(x === 3){
alert('you are correct!');
}else{
alert('try again');
random();
}
}
random();
The guess function's signature says that it takes a parameter x, but you're not passing any value to the function when it's called, so it's assigning undefined to x when it runs guess, which will never equal 3. You can take 2 approaches to fix this. First, you could make x a global variable by getting rid of the let where you define x in the random function and removing x from guess's function signature, like so:
var x;
function random() {
x = Math.floor((Math.random() * 10) + 1);
guess();
}
function guess() {
if (x === 3) {
alert(x + '- you are correct!');
}
else {
alert(x + '- try again');
random();
}
}
random();
Or, you could use x as a parameter for the guess function by removing the var x; global declaration and passing x to guess when you call it in the random function, like so:
function random() {
let x = Math.floor((Math.random() * 10) + 1);
guess(x);
}
function guess(x) {
if (x === 3) {
alert(x + '- you are correct!');
}
else {
alert(x + '- try again');
random();
}
}
random();
I personally wouldn't even have a random function. I'd just define x within guess and call guess from within itself. And, I'd use randojs.com to make the randomness more readable. Here's how I'd do it:
function guess() {
let x = rando(1, 10);
if (x === 3) return alert(x + '- you are correct!');
alert(x + '- try again');
guess();
}
guess();
<script src="https://randojs.com/1.0.0.js"></script>
Note that the return statement would stop the execution of the function right then and there, so it wouldn't progress to the "try again" alert if the number was guessed correctly.
Here's some detailed code that will help you understand how to run such a game in the browser.
See the comments for explanation of how it works (and search for information on MDN to learn more about any particular topic.)
Happy coding!
// Identifies HTML elements
const
guessInput = document.getElementById("guessInput"),
outputParagraph = document.getElementById("outputParagraph");
// Makes a global variable that all functions can access
let globalNum;
// Invokes the main function
playGame();
function playGame(){
// Invokes the randomizer function and stores the result in the global variable
globalNum = getRandomNumber();
//console.log(globalNum);
// Invokes the output function
setOutput("Guess a number from 1 to 10");
// Assigns a function that will be invoked whenever the user changes the input field
guessInput.addEventListener("change", respondToGuess);
// Puts the focus in the input element
guessInput.focus();
}
// Defines a listener function that can automatically see the triggering event
function respondToGuess(event){
// Gets the `target` element of the event and stores it in a local variable
const localReferenceToInputElement = event.target
// The text of an `<input>` element lives in its "value" property
const inputText = localReferenceToInputElement.value;
// Tries to convert the text string to an integer (and store it locally as 'guess')
let guess = parseInt(inputText);
// If the conversion failed, changes the output accordingly
if(!guess){ setOutput("Please enter a valid number"); }
// If the number is out of range, changes the output
else if(guess < 1 || guess > 10){ setOutput("Only numbers from 1 to 10 are allowed"); }
// If the guess doesn't match the stored number, changes the output
else if(guess !== globalNum){ setOutput("Try again..."); }
// If we got this far, the guess was correct, so changes output and ends game
else{
setOutput("You guessed it!");
reset();
}
}
function getRandomNumber(){
// Returns a random number into whatever function called this function
const x = Math.floor((Math.random() * 10) + 1);
return x;
}
function setOutput(outputText){
// The text of a paragraph element lives in its `innerHTML` property
outputParagraph.innerHTML = outputText;
}
function reset(){
// Clears the input and stops listening for changes
guessInput.value = "";
guessInput.removeEventListener("change", respondToGuess);
}
<input id="guessInput" />
<p id="outputParagraph"></p>
I have done some changes to your code.
You have problem with the concept of function calling function.
In real code it will kill your memory.. your function calls function the function not close and call the function again and again... and its fill the memory .
var x;
// flag correct will close the loop when you have right umber
var correct = false;
function random() {
x = Math.floor((Math.random() * 10) + 1);
guess(x);
}
function guess(x) {
if (x === 3) {
alert('you are correct!');
// if number is right flag is up
correct = true;
} else {
alert('the number is ' + x + ' try again');
}
}
// loop until the number is right
while (correct != true) {
random();
}
I'm trying to make a number guessing game on JS for a web dev training I'm on. The problem is that it always prints the keyInYNStrict without giving an another chance for the user. Ignore the fact that the strings and variables are not in English. Basically I want the keyInYNStrict to only come after the arvaus == arvattava is true and the game has ended.
const minLuku = 1;
const maxLuku = 30;
const readlineSync = require('readline-sync');
let arvaus, arvattava, arvaustenLkm
do {
arvaus = readlineSync.question('Ajattelen numeroa 1 ja 30 välillä. Arvaapa vaan');
arvaustenLkm = 1;
arvattava = Math.floor(Math.random() * (maxLuku + 1 - minLuku)) + minLuku
kelvollinen = !isNaN(arvaus) && arvaus > 0 && arvaus < 31;
if (!kelvollinen) {
console.log('Elä viitsi! Laita nyt jokin oikea numero.');
}
else if (arvaus < arvattava){
arvaustenLkm++;
console.log('Kokeile suurempaa lukua.');
} else if (arvaus > arvattava){
arvaustenLkm++;
console.log('Kokeile pienempää lukua.');
} else if (arvaus == arvattava){
console.log('Hienoa. arvasit oikein ' + arvaustenLkm + ' arvauksella.')
}
} while (readlineSync.keyInYNStrict('Haluatko arvata uudestaan?'))
You'll need two while loops nested. The first is to repeat the guessing until the number has been found, the second to ask if the user wished to play again. This becomes clearer if you break a single game into a function, and then wrap "Play again?" around that function.
The following is untested. Notice I also pulled out the "Invalid guess" check to separate it from the game logic. I think that also improves readability, and allows for the option of checking for some other exit condition should the user wish to end early.
EDIT: As I'm thinking about it, there's another problem: Do you want to reset the hidden number each guess? That's probably not consistent with expectations. I've modified the code to reflect.
const minLuku = 1; // Lower bound
const maxLuku = 30; // Upper bound
const readlineSync = require('readline-sync');
let arvaus, arvattava, arvaustenLkm
do {
// Number of guesses
arvaustenLkm = 1;
//Target number
arvattava = Math.floor(Math.random() * (maxLuku + 1 - minLuku)) + minLuku
do {
// User's guess
arvaus = readlineSync.question('Ajattelen numeroa 1 ja 30 välillä. Arvaapa vaan');
// Bad guess test
if (isNaN(arvaus) || arvaus < minLuku || arvaus > maxLuku) {
console.log('Elä viitsi! Laita nyt jokin oikea numero.');
continue;
}
if (arvaus < arvattava){
arvaustenLkm++;
console.log('Kokeile suurempaa lukua.');
} else if (arvaus > arvattava){
arvaustenLkm++;
console.log('Kokeile pienempää lukua.');
} else if (arvaus == arvattava){
console.log('Hienoa. arvasit oikein ' + arvaustenLkm + ' arvauksella.')
}
} while (arvaus != arvattava)
} while (readlineSync.keyInYNStrict('Play again?'))
I'm completing a JavaScript Codecademy course and am having trouble with one of the independent projects that requires you to design a number guessing game. For some reason, when "0" is involved, it returns incorrectly.
JavaScript and I aren't best friends as is, but I had a hard time with what's a relatively simple project and decided to try out one of the "challenge yourself" sections and I just can't make it work at all, or work out what's going wrong.
function generateTarget() {
return Math.floor(Math.random() * 10);
};
function compareGuesses(userGuess, computerGuess, targetNumber) {
function getAbsoluteDistance() {
const uGuess = Math.abs(generateTarget() - userGuess);
const cGuess = Math.abs(generateTarget() - computerGuess);
return uGuess - cGuess
};
if (getAbsoluteDistance() <= 0) {
return true
} else {
return false
};
};
// 'human' is input when return is true; 'computer' when return is false
function updateScore(winner) {
if (winner === 'human') {
humanScore ++;
} else if (winner === 'computer') {
computerScore ++;
};
};
function advanceRound() {
currentRoundNumber +=1;
};
It's essentially a game where the computer generates a random "target" number, you enter a guess number and the computer generates a guess number. Depending on which guess number is closer, you or the computer wins. If you guess the same number, or your guesses are equidistant, the human is meant to win.
This is (just about) working now, except in cases when:
the "target" number is 0. (The computer always wins)
you and the computer guess the same number. (The computer always wins)
you and the computer guess different but equidistant numbers from the target number (The computer always wins)
I'd like to try and get my head around some basic JavaScript so I can move on to something else for a bit, but can't work out what's wrong at all or how to fix it. The only thing that I can identify that these cases have in common is the fact that there's always a "0" somewhere in the absolute distance calculation.
Any help would be massively appreciated!
Kind of made it interactive. From what you say the user wins in the event of a tie or when you guess the same number (a tie). I think the comments indicated why it was failing initially, or at least what is what I see. You were comparing to two different targets, and you can see that in a Fiddle because the results were not consistent.
const userinput = document.getElementById("user");
const computerinput = document.getElementById("computer");
const targetvalue = document.getElementById("target");
const roundcount = document.getElementById("round");
var humanScore = 0;
var computerScore = 0;
var rounds = 0;
document.getElementById("generate").addEventListener("click", function(e) {
targetvalue.value = generateTarget();
});
document.getElementById("calc").addEventListener("click", function(e) {
let result = compareGuesses(userinput.value, computerinput.value, targetvalue.value);
if(result) humanScore++
else computerScore++
rounds++
roundcount.innerHTML = rounds;
alert("Score: Human: " + humanScore + ", Computer: " + computerScore );
});
function generateTarget() {
return Math.floor(Math.random() * 10);
}
function compareGuesses(userGuess, computerGuess, targetNumber) {
const uGuess = Math.abs(targetNumber - userGuess);
const cGuess = Math.abs(targetNumber - computerGuess);
if (uGuess - cGuess <= 0) {
return true
} else {
return false
}
}
<input id = "user" value="" placeholder ="user">
<input id = "computer" value="" placeholder ="computer"><br>
<input id = "target" value="" placeholder ="target">
<button id ="calc" type = "submit">
Submit
</button>
<button id ="generate" type = "submit">
Generate Number
</button><br>
Round: <span id = "round"></span>
The Snippet should allow testing easily. Did not add a thing to generate the computer guess, but that would be similar to generating a target.
I would do like:
function NumGuessGame(){
this.computerScore = this.score = 0;
this.guess = function(num){
if(num === Math.floor(Math.random()*10)){
this.score++;
}
else{
this.computerScore++;
}
return this;
}
}
var gg = new NumGuessGame;
gg.guess(9).guess(11).guess(7).guess(7);
if(gg.computerScore >= gg.score){
console.log('Computer Wins');
}
else{
console.log('You Win');
}
Of course, you should notice that the computer will almost always win under this scenario. You should notice the odds go up here:
function NumGuessGame(){
this.computerScore = this.score = 0;
this.guess = function(num){
if(num === Math.floor(Math.random()*10)){
this.score++;
}
else{
this.computerScore++;
}
return this;
}
}
var gg = new NumGuessGame;
gg.guess(4);
if(gg.computerScore >= gg.score){
console.log('Computer Wins');
}
else{
console.log('You Win');
}
Note that the examples above expect a 0-9 guess or you lose no matter what.
I am trying to create a number generator game where the user has 5 guesses to guess the correct number (between 1 and 10). My code is:
/* Random number generator that compares itself with the user input */
var randomGenerator = Math.floor(Math.random() * 10) + 1;
var turns = 5;
while (turns > 0); {
var user = prompt("Pick a number between one through ten");
var userInput = parseInt(user);
if(userInput === randomGenerator) {
alert("You got it!");
turns = 0;
} else if (userInput > randomGenerator) {
alert("Guess lower!");
--turns;
} else if (userInput < randomGenerator) {
alert("Guess higher!");
--turns;
}
}
alert("The number was " + randomGenerator);
The code runs once and stops. I want it to run over and over until they run out of guesses or they guess the correct number.
you have the semicolon after while
remove that and it will work just fine
I would do something like this for the browser....
// browser with jquery
(function() {
var guesses = 5;
var myRandomNumber = random; // Get random number however you choose
$('#guessInput').on('submit', function (e) {
var guess = $(this).val();
if( guess == myRandomNumber ) {
// show user congratulations
} else {
guesses -= 1;
}
if (guesses === 0) {
// say sorry you are out of guesses
$(this).prop("disabled", true);
}
});
}());
You will have to link this to a button that actually submits and then test the input rather than what I have given you.
So i have been trying this to automatically spawn Creeps in percentage to total living creeps.
however when i run this, it just keeps on spawning harvesters, completely ignoring the conditions even though console.log returns the expected results .
and now i'm clueless about what is going wrong
//creepManager.creations() == counts total creeps and spawns creeps in function of total
var spawnCreep = require('spawnCreep');
var counter = require('counter');
exports.creations=function(){
if( counter.guardCount()/counter.totalCount()<0.5 && counter.harvesterCount()>1){
spawnCreep.guard();
} else if (counter.harvesterCount()/counter.totalCount()<0.3){
spawnCreep.harvester();
} else if(counter.builderCount()/counter.totalCount()<0.2){
spawnCreep.builder();
} else {
spawnCreep.guard(); //default
}
}; // 5guards, 3harvesters, 2 builder per 10CREEPS`
(spawnCreep is another module which keeps track of how the creepers are build)
I was doing something similar in my old code:
function allocateResources() {
var counts = {guard : 0, healer : 0}
for (var name in Game.creeps) {
if (name.indexOf("guard") > -1) {
counts["guard"]++;
} else if (name.indexOf("builder") > -1) {
counts["builder"]++;
}
// ...
counts["total"]++;
}
if (counts["guard"] / (counts["total"] + 1) < 0.51) {
spawnCreep("guard");
} else if (counts["builder"] / (counts["total"] + 1) < 0.34) {
spawnCreep("builder");
}
// ...
}
You should make sure that you avoid division by zero, perhaps that's the bug for you.