Random number is not staying within range javascript [duplicate] - javascript

This question already has an answer here:
Javascript Addition wont work
(1 answer)
Closed 5 years ago.
I have made a Random Number Guess game. The user has to set the minimum and maximum range the random number can be generated in and the number of attempts they get changes dependent on the size of the range they have set. So if the user enters in a minimum of 1 and a maximum of 100 the range will be divided by 10 and rounded up to give the user 10 attempts to guess the number.
The problem I have is that the random number being generated is always way out of the set range and I am not sure why.
My javascript code:
winner = "Well done, you guessed the number correctly";
loser = "Unfortunately you did not guess the number correctly. Game Over!";
higher = "Your guess was too low. Guess higher";
alreadyWon = "You have already guessed correctly. Press f5 to play again";
lower = "Your guess was too high. Guess lower";
gameWon = false;
counter = 0;
function processingFunction(minRange, maxRange) {
randomNo = Math.floor(Math.random() * (maxRange - minRange)) + minRange; //random number generated
attempts = Math.round((maxRange - minRange) / 10); //number of attempts generated
return (randomNo, attempts);
}
function showFunction(guess) {
if (gameWon == true) {
document.getElementById("output1").innerHTML = alreadyWon;
} else if (counter < attempts) {
if (guess == randomNo) {
document.getElementById("output1").innerHTML = winner;
gameWon = true;
} else if (guess > randomNo) {
document.getElementById("output1").innerHTML = lower;
} else {
document.getElementById("output1").innerHTML = higher;
}
counter++;
} else {
document.getElementById("output1").innerHTML = loser;
}
}
<center>
<h2>Random Number Guess</h2>
</center>
<h3>Enter in the minimum range and the maximum range. Accompanied by your first guess</h3>
Minimum Range:<input type="text" id="inputMinRange"></input> Maximum Range:<input type="text" id="inputMaxRange"></input>
<button type="button" onclick="processingFunction(document.getElementById('inputMinRange').value, document.getElementById('inputMaxRange').value)">Set Range</button>
<br><br>
<input type="text" id="guessInput"></input>
<button type="button" onclick="showFunction(document.getElementById('guessInput').value)">Guess</button>
<pre type="text" id="output1"></pre>

The value of an input is always a string, and when you use + where one of the operands is a string, you get string concatenation, not addition. (- will coerce to number, but + will not.) So say we fill in 1 and 100. This:
randomNo = Math.floor(Math.random() * (maxRange - minRange)) + minRange; //random number generated
...takes maxRange - minRange and gets 99 (so far so good), multiplies that by a random value to get (say) 83, and then appends "1" to it to get "831".
You want to convert those values to numbers before feeding them into the function. There are lots of ways to do that (see this answer for a rundown of them, but for instance, the unary +:
<button type="button" onclick="processingFunction(+document.getElementById('inputMinRange').value, +document.getElementById('inputMaxRange').value)">Set Range</button>
<!-- ---------------------------------------------^------------------------------------------------^ -->
Now the function is working with numbers throughout.
Updated snippet:
winner = "Well done, you guessed the number correctly";
loser = "Unfortunately you did not guess the number correctly. Game Over!";
higher = "Your guess was too low. Guess higher";
alreadyWon = "You have already guessed correctly. Press f5 to play again";
lower = "Your guess was too high. Guess lower";
gameWon = false;
counter = 0;
function processingFunction(minRange, maxRange) {
randomNo = Math.floor(Math.random() * (maxRange - minRange)) + minRange; //random number generated
attempts = Math.round((maxRange - minRange) / 10); //number of attempts generated
console.log(minRange, maxRange, randomNo, attempts);
return (randomNo, attempts);
}
function showFunction(guess) {
if (gameWon == true) {
document.getElementById("output1").innerHTML = alreadyWon;
} else if (counter < attempts) {
if (guess == randomNo) {
document.getElementById("output1").innerHTML = winner;
gameWon = true;
} else if (guess > randomNo) {
document.getElementById("output1").innerHTML = lower;
} else {
document.getElementById("output1").innerHTML = higher;
}
counter++;
} else {
document.getElementById("output1").innerHTML = loser;
}
}
<center>
<h2>Random Number Guess</h2>
</center>
<h3>Enter in the minimum range and the maximum range. Accompanied by your first guess</h3>
Minimum Range:<input type="text" id="inputMinRange"></input> Maximum Range:<input type="text" id="inputMaxRange"></input>
<button type="button" onclick="processingFunction(+document.getElementById('inputMinRange').value, +document.getElementById('inputMaxRange').value)">Set Range</button>
<br><br>
<input type="text" id="guessInput"></input>
<button type="button" onclick="showFunction(document.getElementById('guessInput').value)">Guess</button>
<pre type="text" id="output1"></pre>

use below code to convert you are passing a string and + will append the minRange string with generated random no.
randomNo = Math.floor(Math.random() * (maxRange - minRange))+Math.round(minRange);
or
randomNo = Math.floor(Math.random() * (maxRange - minRange))-(-minRange);

Related

Page displays formula rather than result (but for only ONE of the cases)

I'm a student currently learning JavaScript. As practice, I wanted to make a cute reading randomizer for a friend with a simple form and a if else input validation process.
Both of my first two cases function as I expect them two, but the third, the one that actually does the calculation, does not send the result of the calculation to be displayed, but rather the formula. I'm not sure where I went wrong.
function pickfic() {
// Get the value of the input fields
let minNumChosen = document.getElementById('minNum').value;
let maxNumChosen = document.getElementById('maxNum').value;
// If input Not a Number or min bigger than max
let reply;
if (isNaN(minNumChosen) || isNaN(maxNumChosen) || minNumChosen > maxNumChosen ) {
reply = "I think you pissed off my sandwich. Also, those numbers make no sense to me.";
}
// If min is zero
else if (minNumChosen == 0) {
reply = "Really, dude? You have an Excel line for 'zero'?? Witch.";
}
else {
// if range is correct, randomize number
const generateRandomNumber = (minNumChosen, maxNumChosen) => {
return Math.floor(Math.random() * (max - min) + min);
};
reply = "Today, you should read fic number " + generateRandomNumber + "!";
}
document.getElementById("result").innerHTML = reply;
}
For the last case, the page displays : "Today, you should read fic number (minNumChosen, maxNumChosen) => { return Math.floor(Math.random() * (max - min) + min); }!"
You can find the codepen here.
EDIT: Turns out I found another bug, which is probably logic based. It seems that for my function, 2 is greater than 10. So it must be judging by the first digit...
function pickfic() {
// Get the value of the input fields
let minNumChosen = document.getElementById('minNum').value;
let maxNumChosen = document.getElementById('maxNum').value;
// If input Not a Number or min bigger than max
let reply;
if (isNaN(minNumChosen) || isNaN(maxNumChosen) || minNumChosen > maxNumChosen ) {
reply = "I think you pissed off my sandwich. Also, those numbers make no sense to me.";
}
// If min is zero
else if (minNumChosen == 0) {
reply = "Really, dude? You have an Excel line for 'zero'?? Witch.";
}
else {
// if range is correct, randomize number
const generateRandomNumber = (min, max) => {
return Math.floor(Math.random() * (max - min) + min);
};
reply = "Today, you should read fic number " + generateRandomNumber(parseInt(minNumChosen), parseInt(maxNumChosen)) + "!";
}
document.getElementById("result").innerHTML = reply;
}
<input id="minNum" placeholder="min">
<input id="maxNum" placeholder="max">
<div id="result"></div>
<button onclick=pickfic()>Click</button>
You had to add parenthesis to generateRandomNumber()
And also make the minNumChosen and maxNumChosen into integers with parseInt().
There was also another mistake where you didn't name the parameters of your generateRandomNumber function (min, max).
function pickfic() {
// Get the value of the input fields
let minNumChosen = document.getElementById('minNum').value;
let maxNumChosen = document.getElementById('maxNum').value;
// If input Not a Number or min bigger than max
let reply;
if (isNaN(minNumChosen) || isNaN(maxNumChosen) || minNumChosen > maxNumChosen ) {
reply = "I think you pissed off my sandwich. Also, those numbers make no sense to me.";
}
// If min is zero
else if (minNumChosen == 0) {
reply = "Really, dude? You have an Excel line for 'zero'?? Witch.";
}
else {
// if range is correct, randomize number
const generateRandomNumber = Math.floor(Math.random() * (maxNumChosen - minNumChosen) + minNumChosen);
reply = "Today, you should read fic number " + generateRandomNumber + "!";
}
document.getElementById("result").innerHTML = reply;
OR
You created a function which takes in values but you didn't provide the min and max value while calling the generateRandomNumber function
function pickfic() {
// Get the value of the input fields
let minNumChosen = document.getElementById('minNum').value;
let maxNumChosen = document.getElementById('maxNum').value;
// If input Not a Number or min bigger than max
let reply;
if (isNaN(minNumChosen) || isNaN(maxNumChosen) || minNumChosen > maxNumChosen ) {
reply = "I think you pissed off my sandwich. Also, those numbers make no sense to me.";
}
// If min is zero
else if (minNumChosen == 0) {
reply = "Really, dude? You have an Excel line for 'zero'?? Witch.";
}
else {
// if range is correct, randomize number
const generateRandomNumber = (min,max) => {
return Math.floor(Math.random() * (max - min) + min);
};
reply = "Today, you should read fic number " + generateRandomNumber(minNumChosen, maxNumChosen) + "!";
}
document.getElementById("result").innerHTML = reply;
}
I figured out the last bug thanks to #SchokokuchenBäcker's input on the first issue.
My conditional was comparing strings, which is why 20 was smaller than 5 !
Writing the first conditional like this:
if (isNaN(minNumChosen) || isNaN(maxNumChosen) || parseInt(minNumChosen) >= parseInt(maxNumChosen) )
makes it functional!

How can I create a credit card validator using Luhn's algorithm?

I am trying to create a simple credit card validator using Luhn's algorithm. If the check digit matches the last inputted number, then it should alert the user that it is valid. Else, say that it isn't valid. Currently, I am getting an error with my sum (total) coming up as NaN. I assume that is the only problem with the code.
<input type="number" id="creditCard" placeholder="0000 0000 0000 0000">
<input type="submit" id="checkButton" value="CHECK VALIDITY" onclick="checkNumber()">
function checkNumber() {
let number = document.getElementById("creditCard").value;
let multiplier = "212121212121212";
let multipliedNumber;
let multipliedString;
if (number.length != 16) {
alert("Please enter a Credit Card number that is 16 digits in length.");
} else {
for (count = 0; count < number.length - 1; count++) {
multipliedNumber = number[count] * multiplier[count];
console.log(multipliedNumber);
if (multipliedNumber > 9) {
multipliedNumber = multipliedNumber[0] + multipliedNumber[1];
multipliedString = multipliedString + multipliedNumber;
} else {
multipliedString = multipliedString + multipliedNumber;
}
}
console.log(multipliedString);
let checkDigit = 10 - (multipliedString % 10);
if (checkDigit == number[15]) {
alert(`${number} is a valid Credit Card number.`);
} else {
alert(`${number} is not a valid Credit Card number.`);
}
}
}
There are several issues:
multipliedNumber is a product, so it is a number type. Therefore accessing properties like [0] or [1] on it, will just evaluate to undefined. Either turn that value to string first, or (better) use arithmetic to extract the two digits:
multipliedNumber = multipliedNumber % 10 + Math.floor(multipliedNumber/10);
multipliedString is not initialised, so adding things to it will not give the desired outcome. Secondly, you define it as a string, but it should be a number, as with Luhn's algorithm you are supposed to sum up the resulting digits, not concatenate them. So initialise a variable like this:
sum = 0;
... and use it like you did -- although you could benefit from the += operator, and since the operation is the same for both cases, you can do it outside of the if..else blocks.
The calculation of the check digit is wrong when the modulo operation evaluates to 0: 10 - (multipliedString % 10) then returns 10, but in that case the check digit is supposed to be 0. It is much easier to just treat that last digit also in the loop and then check that you have reached a multiple of 10. This is also how the algorithm is explained on Wikipedia
Corrected version:
function checkNumber() {
let number = document.getElementById("creditCard").value;
let multiplier = "2121212121212121"; // One more character added...
let multipliedNumber;
let sum = 0 // Initialise it as a number.
if (number.length != 16) {
console.log("Please enter a Credit Card number that is 16 digits in length.");
} else {
for (count = 0; count < number.length; count++) { // Include last digit in loop
multipliedNumber = number[count] * multiplier[count];
if (multipliedNumber > 9) {
// Use arithmetic to add the two digits
multipliedNumber = multipliedNumber % 10 + Math.floor(multipliedNumber/10);
}
sum += multipliedNumber;
}
let check = sum % 10; // Simpler now because all digits were processed
if (check == 0) { // Sum is multiple of 10
console.log(`${number} is a valid Credit Card number.`);
} else {
console.log(`${number} is not a valid Credit Card number.`);
}
}
}
<input type="number" id="creditCard" placeholder="0000 0000 0000 0000">
<input type="submit" id="checkButton" value="CHECK VALIDITY" onclick="checkNumber()">

Javascript (break)

Im in the process of learning javascript and I cant seem to understand why the break statement isnt functioning :( Can someone please tell me what I've done wrong?
let maximum = parseInt(prompt("Enter the maximum number"));
while(!maximum){
maximum = parseInt(prompt("Enter a valid number"));
}
const randomNum = Math.floor(Math.random() * maximum) + 1;
console.log(randomNum);
let guess = parseInt(prompt(`Enter your guess for the generated number between 1 and the maximum number of ${maximum}.`));
let attempts = 1;
while (parseInt(guess) !== randomNum){
if (guess === 'q') break;
attempts++;
if(guess > randomNum){
guess = prompt("Too high, guess again.");
} else{
guess = prompt("Too low, guess again.");
}
}
if (guess === 'q'){
console.log("Quitting.")
} else {
console.log(`It took you ${attempts} amounts of guesses!`)
}
if (guess === 'q')
You are parsing the value to an integer and are comparing it to a string. Which is always false
So when you type 'q' in your prompt and try parseInt on it you will get NaN which stands for not a number. And NaN is not equal with q obviously
EDIT:
as #axic correctly pointed out the condition from above cannot be fulfilled if q was typed before the iteration begins. But that brings another problem:
On the third iteration you will get another prompt saying "Too low, guess again." even if you guessed the right number, because guess is string and compared to a number which will return false in all cases.
You are parsing the value to an integer and are comparing it to a string.
let maximum = parseInt(prompt("Enter the maximum number"));
while (!maximum) {
maximum = parseInt(prompt("Enter a valid number"));
}
const randomNum = Math.floor(Math.random() * maximum) + 1;
console.log(randomNum);
let guess = prompt(`Enter your guess for the generated number between 1 and the maximum number of ${maximum}.`);
let attempts = 1;
while (parseInt(guess) !== randomNum) {
if (guess === 'q') break;
attempts++;
if (guess > randomNum) {
guess = prompt("Too high, guess again.");
} else {
guess = prompt("Too low, guess again.");
}
}
if (guess === 'q') {
console.log("Quitting.")
} else {
console.log(`It took you ${attempts} amounts of guesses!`)
}
The break statement works totally fine, the issue is in a different location of your logic. You are parsing the integer of guess when displaying the first prompt to enter a guess for the number but when entering anything that isn't a number the value will simply be NaN.
Line 7 is:
let guess = parseInt(prompt(`Enter your guess for the generated number between 1 and the maximum number of ${maximum}.`));
but should be:
let guess = prompt(`Enter your guess for the generated number between 1 and the maximum number of ${maximum}.`);
I'm not entirely sure if this is what you want to achieve but based on the little information you gave I assumed that this would be what you're trying to get.

Javascript, How to count down attempts and alert after certain number of attempts

I tried to set a "How Many Finger" game up where the user inputs a number and only has 5 tries to select the same number as the random number. Then after 3 tries , be alerted that you have 2 tries left, then 1left , then game over, try again. Please don't blast me too hard but my code is set up wrong, I am missing a step somewhere and I am trying to figure out where.
document.getElementById("check").onclick = function() {
//Get a random number between 1 and 5//
var randomNumber = Math.random();
randomNumber = randomNumber * 6;
randomNumber = Math.floor(randomNumber);
//Count the number of guesses the user has//
//User has five attempts to guess correct number//
var guess;
var guessCount = 0;
var numberOfGuesses = 5;
remainingAttempts = numberOfGuesses--;
//This is the value of what the user inputs. If the same as random number alert correct//
//If random number and user input doesnt match alert incorrect//
if (document.getElementById("guess").value == randomNumber) {
alert("Well done, got it!");
} else {
alert("That's not it! Try again");
}
remainingAttempts--;
//Show how many attempts left//
if (guessCount >= 3); {
console.log(remainingAttempts + " tries left");
}
//two guesses left//
console.log("Close but no dice." + remainingAttempts + "tries left")
//1 guess left//
console.log("Last try")
//Game over//
if (guessCount >= 5) {
alert("No more attempts left.Game Over");
return;
}
};
<title>How Many Fingers!</title>
<p> Guess how many fingers!</p>
<p><input type="text" id="guess"> <button id="check">Guess!</button></p>

Javascript validation using isNaN and !==0

I'm new to javascript and I have input boxes that must not allow a zero value or non-numbers. I originaly tried to create a regular expression but I couldn't seem to get any of them to work correctly. I then came up with the following solution but it seems to only work some of the time. I think my if statements are jacked up. Any help with the code as far as making it better would be greatly appreciated.
HTML:
<input name="payrate" id="payrate"></td>
<input name="hours" id="hours" value="0" onclick="dollars()" onchange="dollars()"></td>
Javascript:
function dollars(){
var rate = 0;
rate= document.getElementById("payrate").value;
var hours= document.getElementById("hours").value;
if(!isNaN(hours)){
// !isNan - not a Number
// !rate == 0 - value not equal to 0
if (!isNaN(rate) && !rate == 0) {
//round value of payrate to 2 decimal places
var adjrate = Math.round(rate*100)/100;
document.getElementById("payrate").value="";
document.getElementById("payrate").value= adjrate;
for (i=0; i<6; i++){
document.paycheck['tax'+i].disabled = false;
}
}else{
alert("You entered an invalid rate.\n"+
"Please enter your hourly pay.\n"+
"Example: 8.87 value entered: " + rate);
rate = "";
disableRadio();
resetForm();
}
}else{
alert("You entered invalid or empty hours.\n"+
"Please enter the number of hours worked.\n"+ hours);
hours = "";
disableRadio();
resetForm();
}
}
There is no need to check two times for isNaN. Try to simplify the conditions like this:
function dollars(){
var rate = 0;
rate= document.getElementById("payrate").value;
var hours= document.getElementById("hours").value;
if(!isNaN(hours)){
// !isNan - not a Number
// !rate == 0 - value not equal to 0
if (rate > 0) {
//round value of payrate to 2 decimal places
var adjrate = Math.round(rate*100)/100;
document.getElementById("payrate").value="";
document.getElementById("payrate").value= adjrate;
for (i=0; i<6; i++){
document.paycheck['tax'+i].disabled = false;
}
}else{
alert("You entered an invalid rate.\n"+
"Please enter your hourly pay.\n"+
"Example: 8.87 value entered: " + rate);
rate = "";
disableRadio();
resetForm();
}
}else{
alert("You entered invalid or empty hours.\n"+
"Please enter the number of hours worked.\n"+ hours);
hours = "";
disableRadio();
resetForm();
}
}
You can use <input type="number" min="0.01" step="0.01" value="0.01"> element. See doc. So you will be sure that value rate and hours will be an integer.
As example - you should be able to add whatever you need in this I have commented out some of the additional function calls that were not included - but you should be able to go from here.
<input name="payrate" id="payrate">
<input name="hours" id="hours" value="0" onclick="dollar()" onkeyup="dollar()">
<script>
function dollar(){
var rate = document.getElementById("payrate").value;
var hours= document.getElementById("hours").value;
if(!hours || isNaN(hours)){
alert('hours must be a numeric value greater than zeo');
// disableRadio();
// resetForm();
return false;
}
if (!rate || isNaN(rate)) {
alert('rate must be a numeric value greater than zeo');
//disableRadio();
//resetForm();
return false;
}
var adjrate = Math.round(rate*100)/100;
/**
* commented out for example since not included in example code -
document.getElementById("payrate").value="";
document.getElementById("payrate").value= adjrate;
for (i=0; i<6; i++){
document.paycheck['tax'+i].disabled = false;
}
*/
}
</script>

Categories

Resources