Project III - Holding Current Score
In this lecture, we will implement the functionality of holding the current score. And remember that this happens whenever the user clicks on that button to hold the score.
When that happens, we want to add the current score to the total score followed by switching the player. Switching the player only happens when the score is still below 100 because the current player wins when the score is at least 100. You can check this on the flowchart.
Let's now implement that logic!
We first have to add an event handler to our hold button because we want something to happen whenever a user clicks on that button.
buttonHold.addEventListener('click', function () {
// 1. Add current score to active player's score
// 2. Check if player's score is >= 100
// If >= 100 finish the game
// Else switch to the next player
});
To proceed, we need to define the current player score. If you remember what we said in the last lecture, we will use the below scores variable to store the scores of player zero and player one.
const scores = [0, 0];
player0
is at position zero, and player1
is at position one. And so now we can use the activePlayer
variable to get the correct score of the current player.
// 1. Add current score to active player's score
scores[activePlayer] += currentScore;
Now that we have changed that player's score, we need to display it. We will do it in a similar way as we did for the current score.
document.getElementById(`score--${activePlayer}`).textContent =
scores[activePlayer];
Now, if you give it a save, it will work but not as expected because we haven't yet switched to the next player. That is, right now, as we hold the score, we are not checking if the score is greater than 100, and we are also not switching.
Let's start by switching the player and checking if the score is greater than or equal to 100 for the end.
Switching to the next player is this code that we wrote before:
document.getElementById(`current--${activePlayer}`).textContent = 0;
currentScore = 0;
activePlayer = activePlayer === 0 ? 1 : 0;
player0El.classList.toggle('player--active');
player1El.classList.toggle('player--active');
Knowing that we can't just copy this code and paste it in the hold button event handler because of the DRY principle, let's cut that code from the roll button event handler and put it in a function and call that function in both places where we need it to be executed.
const switchPlayer = function () {
document.getElementById(`current--${activePlayer}`).textContent = 0;
currentScore = 0;
activePlayer = activePlayer === 0 ? 1 : 0;
player0El.classList.toggle('player--active');
player1El.classList.toggle('player--active');
};
// Calling it in roll button event handler
buttonRoll.addEventListener('click', function () {
if (dice !== 1) {
//...
} else {
switchPlayer();
}
});
// Calling it in hold button event handler
buttonHold.addEventListener('click', function () {
//...
switchPlayer();
});
If you save everything and try it, it should now be working as expected. But now, let's get to the final part of this lecture, which is to check if someone reached the final goal of 100 points.
If that happens, the game is over, and we should not be able to click any of the buttons anymore. And we also want to assign a special class to the winner to make it obvious that that player has won.
To add that check, all we have to do is:
// 2. Check if player's score is >= 100
if (scores[activePlayer] >= 100) {
// Finish the game
document
.querySelector(`.player--${activePlayer}`)
.classList.add('player--winner');
document
.querySelector(`.player--${activePlayer}`)
.classList.remove('player--active');
} else {
// Else switch to the next player
switchPlayer();
}
If you give it a save and try it in your browser, everything should be working fine. You will, however, notice some issues like when a player wins, we are still showing the dice, and even worse, we can still click on the different buttons (roll and hold). That is, we can still keep playing the game.
To fix these issues, the easiest solution is to create a variable that holds the state of the game. That is, a variable that tells us if we are still playing or not.
If we are still playing, then we can click any button and then everything will work as normally. But then, as soon as there is a winner, we will say that the game is over, and then we can no longer click on any button.
To implement this logic, we will start by declaring a variable playing
that will be true
because we are playing at the beginning of the game.
let playing = true;
When we finish the game, we set playing
to false
.
if (scores[activePlayer] >= 100) {
// Finish the game
playing = false;
}
Now, since we only want to click on a button when we are playing, we have to put all the logic in our roll and hold button event handlers in an if
condition that will only run if playing
is true
.
buttonRoll.addEventListener('click', function () {
if (playing) {
// 1. Generate a random dice roll
const dice = Math.trunc(Math.random() * 6) + 1;
// 2. Display the dice
diceEl.classList.remove('hidden');
diceEl.src = `dice-${dice}.png`;
// 3. Check if rolled a 1
if (dice !== 1) {
// Add rolled dice to current score
currentScore += dice;
// Assign current score to active player
document.getElementById(`current--${activePlayer}`).textContent =
currentScore;
} else {
// Switch the player
switchPlayer();
}
}
});
buttonHold.addEventListener('click', function () {
if (playing) {
// 1. Add current score to active player's score
scores[activePlayer] += currentScore;
document.getElementById(`score--${activePlayer}`).textContent =
scores[activePlayer];
// 2. Check if player's score is >= 100
if (scores[activePlayer] >= 100) {
// Finish the game
playing = false;
document
.querySelector(`.player--${activePlayer}`)
.classList.add('player--winner');
document
.querySelector(`.player--${activePlayer}`)
.classList.remove('player--active');
} else {
// Else switch to the next player
switchPlayer();
}
}
});
As soon as one player wins, we will finish the game and set playing to false.
if (scores[activePlayer] >= 100) {
// Finish the game
playing = false;
}
The next time we click on any of the buttons, playing will be false, and nothing will be executed. You can give it a save and try it again in your browser, and everything should be good!
In the next lecture, we will finish this project by implementing the reset functionality, which will be executed when we click on the new game button