Whats wrong with my code? - dice rolling - javascript

I am trying to log to the console a message saying : Gratz! You gained 5 points!' after you rolled two the same numbers after each other.
can someone explain me what is wrong with my code?
<script>
var d1 = Math.floor(Math.random()*6) +1;
var diceRolls = [];
function rollDice() {
var die1 = document.getElementById("die1");
var status = document.getElementById("status");
var d1 = Math.floor(Math.random()*6) +1;
console.log("You rolled "+d1+".");
diceRolls.push(d1);
}
if(diceRolls[diceRolls.length - 1] === d1) {
console.log("You won 5 points!");
}
</script>

The problem with your code is that you're checking outside the function, and the condition is not correct. First you need to make sure that the dice has been rolled at least two times, then you compare the two last values. And as #Bergi noted, you also need to call the function, although I guess you're already doing that. Below is the correct solution:
var diceRolls = [];
var totalDiceRolls = 0;
// you set this to whatever you want the limit to be
var maxDiceRolls = 10;
function rollDice() {
if (++totalDiceRolls > maxDiceRolls)
{
alert(maxDiceRolls + " dice rolls allowed at max!");
return;
}
var die1 = document.getElementById("die1");
var status = document.getElementById("status");
var d1 = Math.floor(Math.random()*6) +1;
console.log("You rolled "+d1+".");
diceRolls.push(d1);
if(diceRolls.length > 1 && diceRolls[diceRolls.length - 2] == d1) {
console.log("You won 5 points!");
}
}

You never loop the result, and you assign d1 with a random number, but do nothing with it.
You need to roll the dice and each time, loop the array to find if 2 numbers are the same, at the moment you don't loop, so there is no way to know if 2 numbers are equals.

Related

Issue with negative scores in a simple JS game

I've created a simple JS game where it asks the player to add two random numbers together, and gives them three options to select -- one of the answers is correct and the other two are incorrect. The player only gets 10 seconds to answer each question. When the player selects the correct answer their score is incremented by +1, and it all works as expected.
...Until I tried to add a feature to -1 their score when they get a question wrong (by selecting either of the 2x wrong answers). Everything works as expected when the numbers are positive, however if they get into negatives then weird things start happening and I have no idea why: The score decrements by more than 1, and even when the player gets an answer correct the score still decrements.
As a workaround I tried to add a condition where if the score is below 0 it would reset to 0, so it can't go negative -- however if I do that the score will not increment past 1, no matter how many answers the players get right.
The game and code is here: https://codepen.io/tmnsoon/full/XWVWvmb
let score = 0
function startCountdown(seconds) {
let counter = seconds;
const interval = setInterval(() => {
document.getElementById("timer").innerHTML = counter;
counter--;
if (counter < 0 ) {
clearInterval(interval);
game()
startCountdown(10)
}
}, 1000);
}
function game(){
let answer1 = Math.floor(Math.random()*500)
let answer2 = Math.floor(Math.random()*500)
document.getElementById("challenge").innerHTML = `What is ${answer1} plus ${answer2}`
console.log('Ding!');
let number1 = Math.floor(Math.random()*1000)
let number2 = answer1+answer2
let number3 = Math.floor(Math.random()*1000)
let gameNums = [number1, number2,number3]
shuffle(gameNums)
console.log(gameNums)
document.getElementById("button1").innerHTML = gameNums[0]
document.getElementById("button2").innerHTML = gameNums[1]
document.getElementById("button3").innerHTML = gameNums[2]
function handleClick(event) {
if (event.target.tagName !== "BUTTON") {
return;
}
let buttonValue = event.target.innerText;
if (buttonValue == answer1+answer2){
document
.querySelector("#result")
.innerText = "Correct!";
score++
document.getElementById("score").innerHTML = `Score = ${score}`
game()
}
else if (buttonValue == number1 || number3){
document
.querySelector("#result")
.innerText = "Incorrect!";
score--
document.getElementById("score").innerHTML = `Score = ${score}`
}
}
//listner
document
.querySelector(".buttons")
.addEventListener("click", handleClick);
//end
}
function shuffle(array) {
let currentIndex = array.length, randomIndex;
// While there remain elements to shuffle...
while (currentIndex != 0) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}
return array;
}
If anyone could shed light on what I've done wrong it would be greatly appreciated. Thanks!
The problem is in your else if condition for decreasing the score: else if (buttonValue == number1 || number3).
You're telling the compiler that it should enter that block if the previous if condition is not true AND (if the buttonValue == number1 OR if number3 is truthy).
You probably wanted to write else if (buttonValue == number1 || buttonValue == number3).
Some additional advice: you don't need the condition in the else statement at all, it's enough that the buttonValue isn't the correct answer, there's no need to check which incorrect answer it is.
You can just have else {.

JS for loop not working correctly, trying to loop through an array of variables

I am trying to code the dice game Yahtzee in Javascript for fun. I have a basic interface set up with images of dice. In reference to my problem, a few Yahtzee rules to know would be:
There are 5 dice
After 3 rolls, the player has to pick a points category to score with
Here is the code that is not working:
var die1 = Math.floor((Math.random() * 6) + 1),
die2 = Math.floor((Math.random() * 6) + 1),
die3 = Math.floor((Math.random() * 6) + 1),
die4 = Math.floor((Math.random() * 6) + 1),
die5 = Math.floor((Math.random() * 6) + 1),
dieArray = ["", die1, die2, die3, die4, die5],
optionResult1 = 0;
document.getElementById("option1").onclick = function() {
if (rollCount == 3 & option1 == false) {
for (i=0; i < 5; i++) {
i++;
if (dieArray[i] == 1) {
optionResult1++;
}
if (i = 5) {
option1 = true;
document.getElementById("optionResult1").innerHTML = optionResult1;
console.log("finished");
}
}
console.log(optionResult1);
} else if (rollCount != 3) {
document.getElementById("dialogue").innerHTML = "You cannot pick this yet because you have not rolled 3 times.";
} else if (option1 == true) {
document.getElementById("dialogue").innerHTML = "You cannot pick this because you have already used this category.";
}
}
What should happen (assuming it's the third roll and this points category has not already been chosen previously):
The for loop should go through the dieArray and for each die that is a "one", add 1 to the optionResult1 variable. If there were three "ones" out of five dice, optionResult1 should be "3", etc.
What instead happens is that it usually comes back as 1 less than what it should be. Even if I can see in the console that the array clearly shows three "ones", it will give me "2", or sometimes "0". Is there anything wrong with the code you see? There is obviously other code in the document, but I am fairly certain the problem is within this function. Sorry if this was confusing, it's probably easier to understand if you have played Yahtzee...
I know that I could do the same thing with 5 if statements instead, but I am trying to learn from this and I am fairly confident this SHOULD work, I must just be doing something wrong. Thanks!

How to generate a random number only once, and reuse its output?

I'm learning programming starting with Javascript, and my instructor had us doing a random dice roll, a simple Math.ceil(6*Math.random())
I was trying to slightly gameify it and judge the result. So, if you roll a 7, you win, any other roll you lose. The ultimate result would be,
"You rolled a: 7
You win!"
However, I attempt to accomplish by saying approximately:
console.log("You rolled a: " + diceSum);
if (dicesum() == 7) {
console.log("You win!");
} else {
console.log("Aw... you lose. Better luck next time");
}
diceSum() function evaluates each time, so I may get "You rolled a: 7" and "Aw... you lose" because the first roll was a 7, but by the time the if statement came in, the diceSum was something different.
How do I generate a random number like a dice roll and then reuse its value over and over?
Here's my current code (there is far more than necessary because I'm trying to display the values so I know if it is returning the correct answer):
//Functions
//Generate a random single roll of a dice
var getDieRoll = function() {
return Math.ceil(6*Math.random());
};
//Sum up two dice rolls
var diceSum = function() {
var firstDie = getDieRoll();
var secondDie = getDieRoll();
return firstDie+secondDie;
};
//
//Variables
//Check to see if total sum of the roll is 7
var winMsg = "Winner!"
var loseMsg = "Aw... you lose. Better luck next time."
//
//Outputs
//show total sum to compare with message below
console.log(diceSum())
//Return a message stating the result
console.log("You rolled a " + diceSum())
//View true false status to compare with message returned below
console.log(diceSum()==7)
//If diceSum is a 7, give winning message, otherwise give losing message
if (diceSum()==7){
console.log(winMsg);
} else {
console.log(loseMsg);
}
You put the result in a variable, and use the variable:
var sum = diceSum();
//Outputs
//show total sum to compare with message below
console.log(sum);
//Return a message stating the result
console.log("You rolled a " + sum)
//View true false status to compare with message returned below
console.log(sum == 7);
//If diceSum is a 7, give winning message, otherwise give losing message
if (sum == 7){
console.log(winMsg);
} else {
console.log(loseMsg);
}
By the way, the way to calculate the random number is wrong. The random method is defined to return a value that is 0 <= n < 1, i.e. it can be zero, but it can never be one.
If you use Math.ceil, the effect is that the result will occasionally be zero, and the chance to get a six is slightly smaller than the other numbers.
Use Math.floor instead:
function getDieRoll() {
return Math.floor(6 * Math.random()) + 1;
};
Save it to a variable:
var sum = diceSum();
console.log("You rolled a " + sum);
if (sum == 7) {
console.log(winMsg);
} else {
console.log(loseMsg);
}
Or:
var sum = diceSum(),
msg = sum == 7 ? winMsg : loseMsg;
console.log("You rolled a " + sum);
console.log(msg);

Javascript: generate random numbers in range, avoiding previous two

I'm creating a slider with 6 slides, and I want to randomly move between them, making sure that neither of the previous two slides are shown as the next slide. The functionality doesn't really matter, since what I'm really doing is generating random numbers and keeping track of the previous two. The first slide is always numbered 1, so for the first two iterations that'll be one of the previous numbers that can't be used.
Here's what I have so far, and it works fine for generating the random numbers in the range, but 'caching' the last two values doesn't work reliably:
var rand = Math.floor(Math.random() * 6) + 1;
var prev1 = 1;
var prev2;
function randomSlide() {
// 5 second interval between slides
// Don't show either of previous two slides next
random = setInterval(function() {
prev2 = prev1;
prev1 = rand;
do {
rand = Math.floor(Math.random() * 6) + 1;
} while (rand == prev1 || rand == prev2);
prev1 = rand;
$('#slider').anythingSlider(rand);
//console.log(prev1,prev2);
}, 5000);
}
function firstSlide() {
firstTime = setTimeout(function() {
randomSlide();
}, 5000);
}
firstSlide();
randomSlide();
It's quite simple I think but my brain's getting frazzled trying to parse the values of the two 'cache' variables at the first, and then each subsequent, iteration.
I'm executing a single iteration at the beginning because if randomSlide() executes on load then the first (welcome) slide doesn't get a chance to display.
When you do the prev1 = rand the second time after you've changed the value of rand, you're assigning the new slide's number to it. The next time you enter the loop you do prev2 = prev1, and since prev1 == rand it means that now all three variables prev1, prev2 and rand are the same. Just remove the second prev1 = rand.
Another issue is that you set the interval twice: first you call firstSlide() which executes randomSlide() after a 5 second delay (which sets one interval), then right after you call randomSlide() again which sets another interval.
Here's another (simpler?) approach to getting the result:
<script>
// Return a random number from 1 to 6, exclude
// the last two numbers.
var getRandom = (function() {
var a = [1,2,3,4,5,6];
return function() {
var i = (Math.random() * 4 ) | 0;
a[5] = a.splice(i,1);
return a[5];
}
}());
function writeRandom() {
document.getElementById('d0').innerHTML += getRandom() + '<br>';
}
setInterval(writeRandom, 100)
</script>
<div id="d0"></div>
Not exactly random for the first 2 iterations, but you can fix that by randomising the array when it's initialised. But likely it doesn't matter for a slide show.
It's less code, but the splice part makes it slower in the browsers I tested. My version of the OP is:
var getRandom2 = (function() {
var r0 = r1 = r2 = 1;
return function() {
r0 = r1;
r1 = r2;
do {
r2 = Math.floor(Math.random() * 6) + 1;
} while (r2 == r0 || r2 == r1);
return r1;
}
}());

General Looping question

var answer = " ";
var correct = "4";
var question = "What is 2 * 2?";
for(i = 2; i < 5; i++) {
answer = prompt(question, "0");
if (answer == correct) {
alert("Your answer is correct!");
break;
}
}
How many chances would the user have before the break command got executed?
The user would have 3 chances unless they guessed right on the 1st or 2nd chance. Then they would only have 1 or 2 chances respectively.
i = 2 in the first iteration, i = 3 in the next iteration and i = 4 in the last iteration. Before another iteration starts i is set to 5 and the condition fails.
The user will have 3 chances (i=2, i=3 and i=4).

Categories