user7500403
user7500403

Reputation:

javascript not updating the text of p tag

I have made a simple game using html, css and javascript. Image of the game interface is shown belowenter image description here

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.

Problem

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

Answers (2)

malifa
malifa

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

Phil
Phil

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

Related Questions