Reputation:
I have made a simple game using html
, css
and javascript
. Image of the game interface is shown below
Working of this game
In this game, each player, on his turn, rolls the dice. The number on the dice gets added to current player's current score
. Each player rolls dice until dice rolls to 1
or if the player clicks on hold score
label.
If dice rolls to 1
, current player's current score
becomes 0
. During his turn, any player can choose to hold score
which will add that player's current score
to his total score
, displayed above the current score
, and the then next player takes his turn.
First player whose total score becomes equal to or greater than 100
, wins. Any player's victory is indicated by alert
method of javascript
.
Example case :
Consider a case where player 1
's total score
is 95
and then player 1
rolls the dice and the dice rolls to 5
. Now player 1
chooses to hold score
, so player 1
's total score
and current score
should add up and the total score
should become 100
and then the alert is generated indicating that player 1 has won
. Problem is that, when any player's total score gets equal or greater than 100
, alert is generated correctly but before generating the alert, that player's total score
should update which doesn't happens.
PS. When the total score
is not greater than or equal to 100 for any player, that player's total score
updates without any problem. Problem only seem to arise when total score
becomes greater than or equal to 100
Need help to identify what's causing this issue.
Following code is responsible for updating each player's total score when player chooses to hold score
document.getElementById('hold-score-label').onclick = function () {
//take current score and add it to total score of current player
var playerTotalScore = document.getElementById('player'+playerTurn+'-dice-roll-score');
playerTotalScore.textContent = currentScoreVal + parseInt(playerTotalScore.textContent);
//set current score of current player to zero
document.getElementById('p'+playerTurn+'-current-score-value').textContent = 0;
//CHECK IF ANY PLAYER HAS WON
if(parseInt(playerTotalScore.textContent) >= 100) {
checkWin(playerTurn);
}
//change player turn
changePlayerTurn();
};
Complete Javascript code
var playerTurn = 1; //1 indicates current turn is of player1
var currentScoreVal = 0; //variable to store current score for "hold score" click event
//HIDE THE PLAYER TURN IMAGE OF PLAYER 2
document.getElementById('player2-turn-img').style.display = 'none';
//ADD ACTIVE CLASS TO PLAYER1
document.getElementById('main-container').classList.add('activePlayer1');
//SET CLICK LISTNER FOR 'ROLL DICE' LABEL
document.getElementById('roll-dice-label').onclick = function() {
var randomNum = Math.floor((Math.random() * 6) + 1);
document.getElementById('dice-image').src = "Images/dice"+randomNum+".png";
setScores(randomNum, playerTurn);
};
//FUNCTION THAT UPDATES CURRENT PLAYER'S SCORES
//RANDOM NUMBER GENERATED IN PREVIOUS FUNCTION IS PASSED AS ARGUMENT TO THIS FUNCTION
//CURRENT PLAYER TURN IS ALSO PASSED TO THIS FUNCTION
function setScores (diceNumber , currentPlayer) {
//GET HTML ELEMENT OF CURRENT SCORE BASED ON CURRENT PLAYER
var currentScore = document.getElementById('p'+currentPlayer+'-current-score-value');
//GET HTML ELEMENT OF TOTAL SCORE BASED ON CURRENT PLAYER
var diceRollScore = document.getElementById('player'+currentPlayer+'-dice-roll-score');
if(diceNumber > 1) {
currentScoreVal = parseInt(currentScore.textContent) + diceNumber;
currentScore.textContent = currentScoreVal;
}
else {
//SET CURRENT SCORE OF CURRENT PLAYER TO ZERO
currentScore.textContent = 0;
changePlayerTurn();
}
}
//FUNCTION TO CHECK IF CURRENT PLAYER'S SCORE IS GREATER THAN 100 OR NOT
function checkWin(currentPlayer) {
alert('Player '+ currentPlayer +' has won');
resetGame();
}
//FUNCTION THAT RESETS GAME TO ITS INITIAL STATE
function resetGame() {
//reset the current player turn indicator image
document.getElementById('player1-turn-img').style.display = "inline-block";
document.getElementById('player2-turn-img').style.display = 'none';
//set dice image to 'dice1.png'
document.getElementById('dice-image').src = "images/dice1.png";
//set current scores of both players to zero
document.getElementById('p1-current-score-value').textContent = 0;
document.getElementById('p2-current-score-value').textContent = 0;
//set total score of both players to zero
document.getElementById('player1-dice-roll-score').textContent = 0;
document.getElementById('player2-dice-roll-score').textContent = 0;
//set active player background color to player1 panel
document.getElementById('main-container').classList.remove('activePlayer2');
document.getElementById('main-container').classList.add('activePlayer1');
}
//CLICK LISTNER FOR HOLD SCORE LABEL
document.getElementById('hold-score-label').onclick = function () {
//take current score and add it to total score of current player
var playerTotalScore = document.getElementById('player'+playerTurn+'-dice-roll-score');playerTotalScore.textContent = currentScoreVal + parseInt(playerTotalScore.textContent);
//set current score of current player to zero
document.getElementById('p'+playerTurn+'-current-score-value').textContent = 0;
//CHECK IF ANY PLAYER HAS WON
if(parseInt(playerTotalScore.textContent) >= 100) {
checkWin(playerTurn);
}
//change player turn
changePlayerTurn();
};
//FUNCTION TO CHANGE CURRENT PLAYER TURN
function changePlayerTurn() {
if(playerTurn === 1) {
playerTurn = 2;
document.getElementById('main-container').classList.add('activePlayer2');
document.getElementById('player1-turn-img').style.display = "none";
document.getElementById('player2-turn-img').style.display = 'inline-block';
}
else {
playerTurn = 1;
document.getElementById('main-container').classList.remove('activePlayer2');
document.getElementById('player1-turn-img').style.display = "inline-block";
document.getElementById('player2-turn-img').style.display = 'none';
}
}
You can test this game yourself : codepen
Please note that images shown in the interface above wont show. So dice image wont show but it will update score values when you click on roll dice
label.
Upvotes: 1
Views: 1515
Reputation: 8165
It's a matter of timing. Updating the DOM just takes a bit longer then the code which is executed after you set the total score. That's why your alert shows nearly the same moment you wait for the DOM update.
Just use a timeout, then you'll see better what's happening.
function checkWin(currentPlayer) {
setTimeout(() => {
alert('Player '+ currentPlayer +' has won');
resetGame();
}, 1000);
}
(The alert prevents the re-rendering of your DOM and after the Alert the score is reset immediately, thus you see no changes)
And FYI: There's a little bug in your game: If you roll your dice and then keep pressing "Hold the score" you'll get the same points every turn.
Upvotes: 2
Reputation: 2807
I believe it is an issue with the alert blocking the main thread, before the page has been updated.
To avoid this, try to place the checkWin function call into a window timeout, effectively decoupling the alert showing from the page update.
setTimeout(function(){checkWin(playerTurn)}, 10);
If you used an on-page alert (effectively showing the result in a div that would not block the page update) then you would be able to avoid this issue.
Upvotes: 3