How do I pick the closest integer to a random number? - javascript

I tried to make a small game were you have to guess which number the computer will pick. The pick that is closer to the number should win. Now I don't know how to write an if/switch that compares the values and chooses the one that is closer to the secretNumber.
This is my current code for evaluating who won. As you can see, I can only work with winners having the exact same number as the secret one.
if (user1Guess == user2Guess && user1Guess == secretGuess) {
console.log(`TIE!`)
} else if (user1Guess == secretNumber && user2Guess !== secretNumber){
console.log(`Player 1 wins!`)
} else if (user1Guess !== secretNumber && user2Guess == secretNumber)
{
console.log(`Player 2 wins!`)
};

Take the absolute value of the difference between each guess and the secretNumber. The closest guess will be the one whose difference is smaller:
const user1Diff = Math.abs(user1Guess - secretGuess);
const user2Diff = Math.abs(user2Guess - secretGuess);
if (user1Diff === user2Diff) {
console.log('Tie');
} else if (user1Diff > user2Diff) {
console.log('Player 2 wins');
} else {
console.log('Player 1 wins');
}

You canuser Math.abs() to get difference between user guesses and secretNumber to compare and decide who wins.
Hope this snippet helps:
const user1Guess = Math.floor(Math.random() * 100) + 1, // Random number between 1-100 to mock user input
user2Guess = Math.floor(Math.random() * 100) + 1, // Random number between 1-100 to mock user input
secretNumber = Math.floor(Math.random() * 100) + 1, // Random number between 1-100 to mock computer pick
user1Diff = Math.abs(user1Guess - secretNumber),
user2Diff = Math.abs(user2Guess - secretNumber);
if (user1Diff === user2Diff) {
console.log(`TIE!`)
} else if (user1Diff < user2Diff) {
console.log(`Player 1 wins!`)
} else if (user1Diff > user2Diff) {
console.log(`Player 2 wins!`)
} else {
console.log(`You broke the game, congrats!`)
}
Btw, you have a typo at first if statement: secretGuess needs to be secretNumber

Let's think about what it means for a guess to be closer.
If x is closer to n than y is. Then the distance from x to n must be less than the distance from y to n.
With numbers, the distance from x to n is abs(n - x), which is the absolute value of the difference. The absolute value is always non-negative number. For example, the absolute value of -3 is 3.
So if x is closer to n than y is, that must mean that the following is also true:
Math.abs(n - x) < Math.abs(n - y)
You can then use these in your if statement conditions.
const user1Distance = Math.abs(secretNumber - user1Guess);
const user2Distance = Math.abs(secretNumber - user2Guess);
if (user1Distance === user2Distance) {
console.log("TIE!");
} else if (user1Distance < user2Distance) {
console.log("Player 1 wins!");
} else {
console.log("Player 2 wins!");
}

Related

Random number upper limit and lower limit

I'm working on a random number guessing game in JavaScript. I want the user to input a lowLimit and a highLimit and have the random number generated between those two numbers. I tried hardcoding the lowLimit and highLimit as below:
let lowLimit = 5;
let highLimit = 20;
let random = Math.floor(Math.random() * highLimit);
if (random < lowLimit) {
random += lowLimit;
}
console.log(random);
and everything works well.
However, when I allow the user to input values, the random number always becomes the sum of lowLimit and upperLimit. I cannot figure this out!
My final code is this:
let lowLimit = prompt('Input the lower limit:');
let highLimit = prompt('Input the upper limit:');
let random = Math.floor(Math.random() * highLimit);
let tries = 0;
if (random < lowLimit) {
random += lowLimit;
}
console.log(random);
let guess = prompt('Secret number generated. Enter guess:');
while (guess !== random) {
if (guess === 'q') break;
tries += 1;
if (guess > random) {
prompt('You guessed too high. Guess again...');
} else if (guess < random) {
prompt('You guessed too low. Guess again...');
} else {
alert('You guessed correctly! You made ' + tries + " guesses.");
}
}
This solution works. Any refactoring suggestions are welcome.
let lowLimit = Number(prompt('Input the lower limit:'));
let highLimit = Number(prompt('Input the upper limit:'));
while (!lowLimit || !highLimit) {
lowLimit = Number(prompt('Input a valid lower limit:'));
highLimit = Number(prompt('Input a valid upper limit:'));
}
lowLimit = Number(lowLimit);
highLimit = Number(highLimit);
let random = Math.floor(Math.random() * (highLimit - lowLimit) + lowLimit);
let guesses = 0;
console.log(random);
guess = prompt('Enter guess:');
while (guess !== random) {
if (guess === 'q') {
alert('Ok. Quitting... You made ' + guesses + ' guesses')
break;
}
guesses += 1;
guess = Number(guess);
if (guess > random) {
guess = prompt('You guessed too high. Guess again...');
} else if (guess < random) {
guess = prompt('You guessed too low. Guess again...');
} else alert('You guessed correctly! You made ' + guesses + " guesses.");
}
A few tweaks to improve the code, and one bug fix (the case where user guesses correctly on the first try, they will receive no feedback)...
// + is concise way to coerce an int
const lowLimit = +prompt('Input the lower limit:');
const highLimit = +prompt('Input the upper limit:');
// note - we could add checks here for invalid or disordered values
// this presumes we want random to be exclusive of highLimit. if not, we'll need to tweak
const random = Math.floor(Math.random() * (highLimit - lowLimit) + lowLimit);
// we'll vary the prompt during the game
let promptMsg = 'Enter guess:', guesses = 0, guess;
// bug fix and cleanup: do while, so we always play at least once
// prompt in just one place, alter the prompt message to represent game state
do {
guess = prompt(promptMsg);
guesses++;
if (guess !== 'q') {
guess = +guess;
if (guess > random) {
promptMsg = 'You guessed too high. Guess again...';
} else if (guess < random) {
promptMsg = 'You guessed too low. Guess again...';
}
}
} while (guess !== 'q' && guess !== random);
const endMsg = guess === 'q' ? 'Ok. Quitting' : 'You guessed correctly.'
const guessesMsg = `You made ${guesses} ${guesses === 1 ? 'guess' : 'guesses'}`;
alert(`${endMsg} ${guessesMsg}`)
We can generate a random number by using the Date.now()
let res = Date.now() % (highLimit - lowLimit + 1) + lowLimit.
This is because nobody can estimate the time in milisecond the code runs.

How do I make a continuous loop for "confirm" alert in javascript

So I'm kinda new to Javascript, so sorry if this question sounds pretty basic. So I'm trying to make a guessing game where the computer guesses the number the user is thinking. I want to make it so that no matter how many times the user clicks "cancel" a new random number will show up until it the computer "guesses" the number the user was thinking. but i cant figure out how to make a loop out of that.
here's my code:
const guesser = () => {
let min = 0;
let max = 100;
let guess;
alert("Think of a number between 0 and 100");
while (min <= max) {
guess = Math.round((min + max) / 2);
if(confirm("is your number " + guess) == false){
if(confirm("if your number is higher, please click 'ok'. If its lower please click 'cancel'") == false){
if (confirm("is your number " + Math.floor(Math.random() * guess)) == true){
alert("haha got your number!")
}
}
else if (confirm("is your number " + Math.floor((Math.random() * 50) + guess)) == true){
alert("haha got your number!")
}
}
else {
alert("haha got your number!")
}
return;
}
alert("I could not guess your number. I think you are cheating!");
};
You ask the user to tell you if their number is higher or lower than your guess, but you need to do something with that information. Specifically, if their number is greater than the current guess, increase the guess by bringing the minimum up to the current guess. If their number is less than the current guess, decrease the guess by bringing the maximum down to the current guess.
function main() {
var min = 0;
var max = 100;
alert(`Think of a number between ${min} and ${max}`);
while (min<max) {
var guess = Math.round((min + max) / 2);
if(confirm("is your number " + guess)) {
alert("haha got your number!")
return;
} else {
if(confirm("if your number is higher, please click 'ok'. If its lower please click 'cancel'")) {
min = guess+1;
} else {
max = guess-1;
}
}
}
alert("I could not guess your number. I think you are cheating!");
}
main();
Here is another way to achieve what you're looking for:
document.addEventListener("DOMContentLoaded", function(event) {
const guesser = () => {
let min = 0;
let max = 100;
let guess;
alert("Think of a number between 0 and 100");
while (min <= max) {
// initial guess
guess = Math.round((min + max) / 2);
if (confirm("is your number " + guess) == false) {
if (confirm("if your number is higher, please click 'ok'. If its lower please click 'cancel'") == false) {
// number is lower than guess
max = guess;
} else {
// number is higer than guess
min = guess
}
} else {
alert("guessed your number!")
return
}
}
}
guesser();
});
<html>
<head>
</head>
<body>
Hello World!
</body>
</html>

How to write a while loop inside an if-else loop

Please tell me what is wrong with my code. It seems like after continue; it still loops over the same block even if I use the largest number as an input. Here it still wants me to input a larger number:
// 1) Generate a random integer from 0 to 10 (reference: Math.random())
const RanNum = Math.floor(Math.random() * Math.floor(11))
console.log(RanNum)
// 2) Ask the user input (reference: prompt())
let userInput = prompt(`Give me a number`)
const userInputInt = parseInt(userInput)
console.log(userInput)
console.log(typeof(userInput))
console.log(userInputInt)
console.log(typeof(userInputInt))
if(isNaN(userInput)){
prompt(`Give me a freaking number`)
}else{
let x = 0;
while (x < 4) {
console.log('hi')
console.log(userInputInt)
console.log(RanNum)
if (userInputInt == RanNum) {
console.log(`win`)
prompt('YOU GOT IT MAN')
break;
}
else if (userInputInt < RanNum) {
x = x+1 ;
prompt('Larger please')
continue;
}
else if (userInputInt > RanNum) {
x= x+1
prompt('Smaller please')
continue;
}
}
if(x > 3){alert('More than 3 times')}
}
However, this one works fine. Can someone point to me what's wrong?
// Guess the number
const randomNumber = Math.floor(Math.random() * 11);
let trials = 0;
while(trials < 4){
const guess= parseInt(prompt("Give me a number(0-10)!"));
if(isNaN(guess)){
alert("You are not inputing a number");
// Works for while-loop, for-loop, do-while loop
continue;
}
trials++;
if(guess === randomNumber){
// Equal
alert("You win!!");
// If the player wins, terminate the game
// Works for while-loop, for-loop, do-while loop
break;
}else{
// Unequal
if(guess > randomNumber){
alert("Too large!");
}else{
alert("Too small");
}
}
}
if(trials > 3){
alert("You loses");
}
You can use switch-case except if-else:
let i = 0,
solution = Math.floor(Math.random() * Math.floor(11)),
max_tries = 3;
while (nmb !== solution && i < max_tries + 1) {
if (i < max_tries) {
var nmb = Number(prompt("Put number (1 - 10): "));
switch(true) {
case nmb > solution : console.log("Smaller please"); break;
case nmb < solution : console.log("Largest please"); break;
default : console.log("YOU GOT IT MAN");
}
}
else { console.log("You lose! Number was: " + solution) }
i++
}
You only need to add outputs to the console as in your variant.

How to ask a user to guess a number between 1 - 1000

I'm trying to write some javascript code that asks the user to guess a number from 1 to 1000 and enter it into the prompt box. If the user guesses right, an alert box will pop up saying they got it right. If they guess wrong, another alert box will popup and say that they are wrong and to try once more.
The issue here is that I don't know what I have to do to make the code loop infinitely until they get the right answer. Here's what i have so far:
var a = 489; // the number that needs to be guessed to win the game.
//var b stores whatever value the user enters.
var b = prompt("Enter a number in between 1 and 1000");
// if/else statement that test if the variables are equal.
if (b == a) {
alert("You're right!");
} else {
alert("Incorrect! Try again!");
}
Number matching
Basically, when you make prompt, it returns a String or text, not a number. To fix this, do:
if (parseInt(b,10) === a) {
//Code
}
Other ways
They're a lot of ways to parse numbers. Here's a few more:
parseFloat(b); // Also parses decimals: '5.3' -> 5.3
parseInt(b, 10); // Gives an integer (base 10): '5.3' -> 5
+b; // A very 'short' way; '5.4' -> 5.4
Number('5.4e2'); // Number case: '5.4e2' -> 540
Looping
Now to repeat? Make it a loop!
var a = 432;
while (true) {
var b = prompt("Enter a number in between 1 and 1000");
if (b == a){
alert("You're right!");
break; // Stops loop
} else if (!b) { break; }
else {
alert("Incorrect! Try again!");
}
}
Not sure why, but some people hate while true loops. They shouldn't cause any problems as long as you coded it properly
Random Numbers
You can get a random number using Math.random.
var min = 1,
max = 1000;
Math.floor(Math.random() * (max - min + 1)) + min;
If you're like me and want short code, you can shorten it by:
Math.floor(Math.random() * (999)) + 1;
All Together Now!
var a = Math.floor(Math.random() * (999)) + 1;
while (true) {
var b = prompt("Enter a number in between 1 and 1000");
if (b == a) {
alert("You're right!");
break; // Stops loop
} else if (!b) {
alert("The Correct Answer was: " + a); //Shows correct answer
break;
} else {
alert("Incorrect! Try again!");
}
}
Just stick your prompt in some kind of loop. The code will inside the loop will run over and over until the comparison is false.
Basic example:
http://jsfiddle.net/s2he1twj/
var a = 500,
b;
while (parseInt(b) !== a) {
b = prompt('Enter a number!');
if (b === null) break;
}
while loop
Do this recursively by calling the same function like
var a = 489;
function promptGuess(){
//var b stores whatever value the user enters.
var b = prompt("Enter a number in between 1 and 1000");
// if/else statement that test if the variables are equal.
if (b == a){
alert("You're right!");
} else {
alert("Incorrect! Try again!");
promptGuess();
}
}
promptGuess();
Use a while until the match:
var a = 489;
var b;
while(b != a) {
var b = prompt("Enter a number in between 1 and 1000");
if (b == a) {
alert("You're right!");
} else {
alert("Incorrect! Try again!");
}
}
One more thing: although the b != a evaluation is correct, it's error-prone. The != operator do conversion type, whilst the !== operator compares types and value.
In your case: 5 != '5' will return false, but 5 !== '5' returns true. It's recommended that your comparisons be conversion-free. It's more strict.
In your case, this means:
while(parseInt(b) !== a)
Greetings!

Very basic dice game in Javascript - trying to log 'wins' variable

I'm trying to make a very basic dice game (new to Javascript). On the page load, the 'dice' is 'rolled' three times and the results are displayed, with a message to say whether you managed to roll a 6 or not. I'm trying to put in a permanant message about how many games have been won - problem is, if you look at my code below, the variable I'm using for this 'wins' is incremented each time there is a win, but it only actually displays two values: 0 if the user just lost, and 1 if it was a win. It never gets to a higher number no matter how many times the dice is rolled. Wondering if anyone has a solution/explanation?
Code:
console.log("Dice game. You have 3 tries to roll a 6 - go");
var rolls = 0;
var wins = 0;
function rollDice() {
var dice = Math.random();
if (dice <= .17) {
dice = 1;
}
else if (dice <= .33) {
dice = 2;
}
else if (dice <= .50) {
dice = 3;
}
else if (dice <= .67) {
dice = 4;
}
else if (dice <= .84) {
dice = 5;
}
else if (dice <= 1) {
dice = 6;
}
return dice;
}
function diceGame() {
do {
var dice = rollDice();
console.log(dice);
rolls++;
if (dice === 6) {
console.log("You won!");
wins++;
if (rolls === 1) {
console.log("It took " + rolls + " try");
}
else {
console.log("It took " + rolls + " tries");
}
break;
}
}
while (rolls <= 2);
if (dice !== 6) {
console.log("You lost");
}
}
diceGame();
console.log("Times won: " + wins);
The value 1 will never be hit, because:
The Math.random() function returns a floating-point, pseudo-random
number in the range [0, 1) that is, from 0 (inclusive) up to but not
including 1 (exclusive), which you can then scale to your desired
range. The implementation selects the initial seed to the random
number generation algorithm; it cannot be chosen or reset by the user.
Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
How are you running the code? Each time it runs, it resets the wins variable to 0. You need to call the function with a button, or something so it doesn't have to refresh the code block to run a second time.
Some improvements ;)
Call continue instead of break MDN continue
Change rollDice function Random number from range
anonymous function for create namespace
// namespace for our variables
(function(){
console.log("Dice game. You have 3 tries to roll a 6 - go");
var rolls = 0;
var wins = 0;
function rollDice() {
// simple random from range ( https://stackoverflow.com/a/1527820/2746472 )
return Math.floor(Math.random()*6)+1;
}
function diceGame() {
do {
var dice = rollDice();
console.log(dice);
rolls++;
if (dice === 6) {
console.log("You won!");
wins++;
if (rolls === 1) {
console.log("It took " + rolls + " try");
} else {
console.log("It took " + rolls + " tries");
}
continue; //instead of break!
}
} while (rolls <= 2);
if (dice !== 6) {
console.log("You lost");
}
}
diceGame();
console.log("Times won: " + wins);
})();
Your rollDice function can be simplified to 1 line.
var dice = Math.floor(Math.random() * 6) + 1;
It's because you have a break if you win so it exits the loop after the first win.

Categories