JS receiving NaN when trying to add number to a variable - javascript

I am trying to code a roll dice game, but I constantly get a NaN number in my console.
var dice, score;
function rollDice() {
dice = Math.floor((Math.random() * 6) + 1);
dice !== 1 ? score += dice : score = 0;
return score;
}
var hey = rollDice();
console.log(hey);

You need to assign a default value to the score variable, like score = 0, because now it's undefined. Example: JSFiddle

Your variable score is never initialized to a value, so when performing this operation:
score += dice
It is really performing:
undefined += 3
And undefined + a number is always NaN.
Try initializing score to 0:
var dice = 0;
var score = 0;
var dice = 0;
var score = 0;
function rollDice() {
dice = Math.floor((Math.random() * 6) + 1);
dice !== 1 ? score += dice : score = 0;
return score;
}
var hey = rollDice();
console.log(hey);

Your terniary is what's causing the NaN. Try this.
score = dice !== 1 ? (dice + 1) : 0;
Example: https://repl.it/NKul/1
EDIT
Fixed true condition for terniary.

Related

While loop multiple statements in js. "The Dice Game"

I have to create a dice roller game, if it lands on 2,3,6,12 the game is supposed to stop and tell me which of the numbers the sum of both my dices landed on and how many "rolls" or tries it took me to get there. I haven't been able to figure out why my program isn't working, if I erase the conditions in the while loop and leave only one for example: while(dice != 2); the program will run but it would obviously only match if it lands on 2. Please help me!
function play() {
var dice = -1;
var rolls = 1;
var numb1 = 2;
var numb2 = 3;
var numb3 = 6;
var numb4 = 12;
while (dice != numb1 || dice != numb2 || dice != numb3 || dice != numb4) {
dice = Math.floor(Math.random() * 11) + 2;
rolls++;
}
document.getElementById('results').innerHTML = 'Your dice landed on: ' + dice;
document.getElementById('rolls').innerHTML = 'Rolls: ' + rolls;
}
Change your || to && in your while
function play() {
var dice = -1;
var rolls = 1;
var numb1 = 2;
var numb2 = 3;
var numb3 = 6;
var numb4 = 12;
while (dice != numb1 && dice != numb2 && dice != numb3 && dice != numb4) {
dice = Math.floor(Math.random() * 11) + 2;
rolls++;
}
document.getElementById('results').innerHTML = 'Your dice landed on: ' + dice;
document.getElementById('rolls').innerHTML = 'Rolls: ' + rolls;
}
play()
<div id="results"></div>
<div id="rolls"></div>
you can improve the while condition by using includes
function play() {
var dice = -1;
var rolls = 1;
var numb1 = 2;
var numb2 = 3;
var numb3 = 6;
var numb4 = 12;
while (![numb1, numb2, numb3, numb4].includes(dice)) {
dice = Math.floor(Math.random() * 11) + 2;
rolls++;
}
document.getElementById('results').innerHTML = 'Your dice landed on: ' + dice;
document.getElementById('rolls').innerHTML = 'Rolls: ' + rolls;
}
play()
<div id="results"></div>
<div id="rolls"></div>
Your code doesn't work, because dice would need to be each of these numbers at the same time to work, which is impossible.
Try doing this:
while (![2, 3, 6, 12].includes(dice)) {
Also, your random function can't get 1, maybe try:
Math.floor(Math.random() * 12) + 1

Counting occurrences of integer from random outcome

I'm fairly new to coding and have this practice that I can't figure out the last part of it.
I'm rolling three dice and supposed to count how many combined value of sevens I get at 1000th roll.
Do I have to create an array? the hint given to me was to create a counter variable. But I can't find any solution. I know it must be something simple. I need your guidance!
var getRandomInt = function(x) {
var result = 0;
result = Math.floor((Math.random() * x) + 1);
return result;
};
//variables I need
var diceOne = 0;
var diceTwo = 0;
var diceThree = 0;
var diceSum = 0;
var roll = 0;
var average = 0;
for (var i = 1; i <= 1000; i++) {
//Simulate a Dice Roll
diceOne = getRandomInt(6);
diceTwo = getRandomInt(6);
diceThree = getRandomInt(6);
roll = roll + 1;
diceSum = diceOne + diceTwo + diceThree;
average += diceSum / 1000;
console.log("Roll #" + roll);
console.log("Value of Dice 1 is " + diceOne);
console.log("Value of Dice 2 is " + diceTwo);
console.log("Value of Dice 3 is " + diceThree);
console.log("The Sum of the Dice is " + diceSum);
// Announce average and count of 7s
if (i == 1000) {
console.log("The Average is " + average);
}
}
If you need to count the times the 3 dice add up to 7, you can create a variable to keep track of this.
Inside your loop, you increase this by one everytime diceSum is 7.
var getRandomInt = function(x) {
var result = 0;
result = Math.floor((Math.random() * x) + 1);
return result;
};
//variables I need
var diceOne = 0;
var diceTwo = 0;
var diceThree = 0;
var diceSum = 0;
var roll = 0;
var average = 0;
var sevenCount = 0;
for (var i = 1; i <= 1000; i++) {
//Simulate a Dice Roll
diceOne = getRandomInt(6);
diceTwo = getRandomInt(6);
diceThree = getRandomInt(6);
roll = roll + 1;
diceSum = diceOne + diceTwo + diceThree;
average += diceSum / 1000;
console.log("Roll #" + roll);
console.log("The Sum of the Dice is " + diceSum);
if(diceSum === 7){
sevenCount = sevenCount + 1;
}
// Announce average and count of 7s
if (i == 1000) {
console.log("The Average is " + average);
console.log("The seven count is " + sevenCount);
}
}
They're teaching you something that's actually really good to know.
You don't have to remember all values in order to calculate the average or number of 7s. You only have to count how many 7s you've seen and keep another variables that's the sum of all the values you've seen.
Edit: if you want to count the number of 7s you've seen, you need to create a variable, say count_7s and every time you see a 7, you increment count_7s = count_7s + 1.
You need no roll count, because you loop the same amount, and you need a counter for sevens. An you could take a variable for sum and calculate later the average. This is better in terms of numerical precision.
At the end show the result of average and count of sevens.
var getRandomInt = function(x) {
return Math.floor((Math.random() * x) + 1);
},
sum = 0,
average = 0,
sevens = 0;
for (var i = 1; i <= 1000; i++) {
let diceSum = getRandomInt(6) + getRandomInt(6) + getRandomInt(6);
sevens += diceSum === 7;
sum += diceSum;
}
average = sum / 1000;
console.log("The Average is " + average);
console.log("The Count of Sevens " + sevens);

Checking for two consecutive values match of a variable's value in JavaScript

I built a function called roll() which handles a roll of a dice. I'm trying to read the value of the roll and check if the roll hit 6 twice in a row so that I can interrupt the player's turn and turn it to the next player.
I can read the dice value alright, I'm having trouble trying to figure out how to check for a 6 twice in a row.
This is my function:
roll = function(){
if (gamePlaying){
// 1. Get a random number
//var dice = Math.floor(Math.random() * 6) + 1; //1 to 6 randomly
var dice = 6;
//2. Display the result
var diceDOM = document.querySelector('.dice');
diceDOM.style.display = 'block';
diceDOM.src = 'images/' + 'dice-' + dice + '.png';
//3. Update the roundScore IF the rolled number is not 1
// for type coersion, we need to use !== and not !=
if(dice !== 1) {
//add score
roundScore += dice; // same as roundScore = roundScore + dice
//it outputs to a div of ID = #myId
document.querySelector('#current-' + activePlayer).textContent = roundScore;
} else {
alert('Next Player')
nextPlayer();
}
// Is this right?
for(var i = 1; i >= 2; i++){
if (dice == 6){
console.log('sixes');
}
}
}
}
Being triggered by a button like this:
document.querySelector('.btn-roll').addEventListener('click', function(){
roll();
});
I loaded the game to this CODEPEN
P.S. I put a dice = 6; under the random function so you don't have to play the game until you get two sixes. Just uncomment it and comment out the dice = math function and you'll get nothing but sixes.
I also put a "Is this right?" comment on top of a for loop. What I mean by that is, " is this the right approach?" Should I keep experimenting with a loop or am I way off already?
And by the way, if 2 sixes do come up, the entire score is deleted which is being passed to the score[] But I can do that... I think lol
Many thanks.
You can try something like this, where you make roll() a self invoking function. That way you can store how many times they have rolled a six.
roll = (function(){
var count = 0;
var lastRoll = 0;
return function() {
if (gamePlaying){
// 1. Get a random number
var dice = Math.floor(Math.random() * 6) + 1; //1 to 6 randomly
var thisRoll = dice;
if(dice === 6) {
lastRoll = 6;
count += 1;
} else {
lastRoll = 0;
count = 0;
}
if(thisRoll === 6 && lastRoll === 6 && count === 2) {
alert('You rolled a six twice!');
lastRoll = 0;
count = 0;
// do your stuff for 2 sixes in a row here!
return;
}
//2. Display the result
var diceDOM = document.querySelector('.dice');
diceDOM.style.display = 'block';
diceDOM.src = 'http://sitedev.online/repo/' + 'dice-' + dice + '.png';
//3. Update the roundScore IF the rolled number is not 1
// for type coersion, we need to use !== and not !=
if(dice !== 1) {
//add score
roundScore += dice; // same as roundScore = roundScore + dice
//it outputs to a div of ID = #myId
document.querySelector('#current-' + activePlayer).textContent = roundScore;
console.log(dice);
} else {
alert('Next Player')
nextPlayer();
}
}
}
})();
Just for the heck of it, you don't need any global or outside vars to do this. The trick is, remember that functions are objects. You can read and write properties to them; you can even entirely change a function from within the function (which is the trick to an old JS singleton pattern).
Here's an example. If you say feed it "true", it will update the "last" reference values and return two random dice rolls. If you feed it "false", it will NOT update the previous reference values until you pass in true again (but it still returns a fresh roll). That way, you can keep rolling, hold the initial value, and compare it to a new second value all you want.
<html>
<head>
</head>
<body>
<script>
var rollfunc = function ( updateLast ) {
var d1 = Math.floor((Math.random() * 6) + 1);
var d2 = Math.floor((Math.random() * 6) + 1);
if ( updateLast ) {
rollfunc.d1 = d1;
rollfunc.d2 = d2;
}
return {
dice1 : d1,
dice2 : d2,
bothsixes : ( ( d1 + d2 === 6 ) && ( rollfunc.d1 + rollfunc.d2 === 6 ) )
};
}
var result = rollfunc ( true );
// If you pass in true then d1, d2, and rollfunc.d1, rollfunc.d2 will always be the same
console.log ( "Reference updated: ", result, "d1 = " + rollfunc.d1, ", d2 = " + rollfunc.d2 );
var result = rollfunc ( false );
// If you pass in false, the reference won't change, but the new roll will, you can compare the two
console.log ( "Reference left alone: ", result, "d1 = " + rollfunc.d1, ", d2 = " + rollfunc.d2 );
</script>
</body>
</html>
I get this might be overly academic, but it's useful to know JS can do this.
A little late to this game. But I'm new to JavaScript, and currently on a similar project from udemy.com.
Here's a solution I found that apparently works. I verified it on your CodePen, too.
document.querySelector('.btn-roll').addEventListener('click', function() {
if (gamePlaying) {
// 1. Get a random number
dice = Math.floor(Math.random() * 6) + 1; //1 to 6 randomly
thisRoll = dice;
if (dice === 6) {
lastRoll = 6;
count += 1;
} else {
lastRoll = 0;
count = 0;
}
if (thisRoll === 6 && lastRoll === 6 && count === 2) {
alert('You rolled a six twice!');
lastRoll = 0;
count = 0;
nextPlayer();
// do your stuff for 2 sixes in a row here!
return;
}
//2. Display result
var diceDOM = document.querySelector('.dice');
diceDOM.style.display = 'block';
diceDOM.src = 'http://sitedev.online/repo/' + 'dice-' + dice + '.png';
//3. Update round score if the rollled number was not a 1
if (dice !== 1) {
//Add score
roundScore += dice;
//roundScore = roundScore + dice
document.querySelector('#current-' + activePlayer).textContent = roundScore;
} else {
nextPlayer();
}
}
});
Working on the same problem. Found another solution on udemy. Hope it helps...
var lastRoll;
document.querySelector('.btn-roll').addEventListener('click', function() {
// Generating a random variable
var dice = Math.floor(Math.random() * 6) + 1;
// Check for two consecutive 6's'
if ( dice === 6 && lastDice === 6) {
//If consecutive 6's code goes here
}
lastRoll = dice;
});

javascript: summing even members of Fibonacci series

Yet Another (Project Euler) Fibonacci Question: Using (vanilla) javascript, I'm trying to sum the even numbers <= a given limit:
First, something is wrong with my 'if' statement, as some of the results (below) are wrong:
function fibonacciSum(limit) {
var limit = limit;
var series = [1,2];
var sum = 0;
var counter = 0;
for (var i=1; i<=33; i++) { // 33 is arbitrary, because I know this is more than enough
var prev1 = series[series.length-1];
var prev2 = series[series.length-2];
var newVal = prev1+prev2;
series.push(newVal);
counter ++;
console.log("series "+ counter + " is: " + series);
if (series[i] % 2 === 0 && series[i] <= limit) { // intending to sum only even values less than/equal to arbitrary limit
// sum = sum + series[i];
sum += series[i];
}
/*
var sum = series.reduce(function(a,b) {
/*
possible to filter here for even numbers? something like:
if (a %2 === 0)
*/
return a+b;
});
*/
console.log("SUM " + counter + ": " + sum);
} // for loop
} // fibonacci
fibonacciSum(4000000);
Results:
series 1 is: 1,2,3
SUM 1: 2
series 2 is: 1,2,3,5
SUM 2: 2
series 3 is: 1,2,3,5,8
SUM 3: 2 // looking for a '10' here
series 4 is: 1,2,3,5,8,13
SUM 4: 10
series 5 is: 1,2,3,5,8,13,21
SUM 5: 10
series 6 is: 1,2,3,5,8,13,21,34
SUM 6: 10 // looking for '44' here
Can someone please explain why neither of these working as intended?
if (series[i] % 2 === 0) { ...
... or
if (series[i] % 2 === 0 && series[i] <= limit) { ...
And secondly, as you can see I had also tried to use series.reduce(... but I can't figure how to sum only the even values; is that doable/cleaner?
Thank you,
Whiskey T.
No need for arrays. Use three variables for let's say previous, current and next numbers in fibonacci sequence.
We can also begin the sequence with 2 an 3 because there are no other even numbers that will affect the result.
We initialize the sum of even numbers with 2 because it's the current number and it's even. In a do...while we advance with the numbers in sequence and if the new numbers are even we add them to the sum. Stop when limit is reached.
function fibEvenSum(limit) {
var prev = 1,
current = 2,
next;
var sum = 2;
do {
next = prev + current;
prev = current;
current = next;
if (current >= limit)
break;
if (current % 2 == 0)
sum += current;
} while (true)
return sum;
}
This algorithm can be improved using properties of odd and even numbers:
odd + odd = even
even + even = even
even + odd = odd
This should work for you...
var fibonacciSum = function(limit) {
var nMinus2 = 1, nMinus1 = 2, evensFound = [2], sum = nMinus1;
while (sum <= limit){
var n = nMinus1 + nMinus2;
if (n % 2 == 0){
sum += n;
if (sum > limit){
break;
}
evensFound.push(n);
}
nMinus2 = nMinus1;
nMinus1 = n;
}
console.log("Evens found - " + evensFound);
return evensFound;
};
var evensFound1 = fibonacciSum(4),
evensFound2 = fibonacciSum(10),
evensFound3 = fibonacciSum(60),
evensFound4 = fibonacciSum(1000);
$(evenResults).append(evensFound1
+ "<br/>" + evensFound2
+ "<br/>" + evensFound3
+ "<br/>" + evensFound4);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="evenResults"></div>
A solution in the spirit of the one your attempted — with arrays — though as pointed out, they are not necessary.
var i = 0, sequence = [1, 2], total = 0;
while (sequence.slice(-1)[0] < 4000000) {
sequence.push(sequence.slice(-1)[0] + sequence.slice(-2)[0]);
}
for ( i; i <= sequence.length; i++ ) {
if ( sequence[i] % 2 === 0 ) {
total += sequence[i];
}
}

How are these operators affecting this simple javascript program?

This is probably embarrassingly obvious but I can't seem to figure it out: I've researched what all of these operators mean and commented out what I think they're doing. Apparently total = 55. I thought it would = 11. Where am I going wrong? Thanks a lot.
var total = 0;
var count = 1;
while (count <= 10) { // while "count" is less than or equal to 10 do...
total += count; // total = total + count (total = 0 + count)
count += 1; // count = 1 + 1 (adding 1 to count every loop until count is equal to 11)
};
console.log(total); -> 55
// total is 0 + count
// when the program ends count = 11
// 0 + 11 = 11
Like others have stated in the comments. You are incrementing your count and total. Do one or the other.
Here's what your code is currently doing:
var total = 0;
var count = 1;
var iteration = 0;
var div = document.getElementById("div");
while (count <= 10) {
total += count;
count += 1;
iteration++;
div.innerHTML += "Iteration " + iteration + ": ";
div.innerHTML += "count = " + count + "; ";
div.innerHTML += "total = " + total + ";<br /><br />"
};
<div id="div"></div>
There's several ways you can do this.
One way would be to just increment the count and total by one at each iteration:
var total = 0;
var count = 1;
while (count <= 10) { // while "count" is less than or equal to 10 do...
total++ // Increase the total by 1
count++ // Increase the count by 1
};
document.getElementById("result").innerHTML = total
<div id="result"></div>
but this only gives you a result of 10 because your count is starting at 1
Another way would be to just increment your count, then assign your count to your total outside of the loop:
var total = 0;
var count = 1;
while (count <= 10) { // while "count" is less than or equal to 10 do...
count++ // Increase the count by 1
};
total = count;
document.getElementById("result").innerHTML = total
<div id="result"></div>
Or, remove count altogether:
var total = 0;
while (total <= 10) {
total++;
};
document.getElementById("result").innerHTML = total
<div id="result"></div>
Or, my preferred method, would be to change your loop from a while to a for loop
var total = 0;
for (var i = 0; i <= 10; i++) {
total++;
}
document.getElementById("result").innerHTML = total
<div id="result"></div>
To understand what is happening, try to write:
console.log(total);
console.log(count);
Inside of the while loop body.
You will see how it behaves on every iteration.
count += 1;
means:
count = count + 1;

Categories

Resources