Project III - Resetting the Game
Welcome to the last lecture of this project and this section on DOM and Events Fundamentals. In this lecture, we will implement the functionality of resetting the game at any point in time.
We want to remove the winner class (The class that changes the winner's background color to dark.) and set all the players' scores (Total and current scores) back to zero when we click on the new game button.
Essentially, we need to set back all the initial conditions of the game.
We already did something similar in our first game (Guess My Number), so maybe this is an excellent opportunity to leave this as a challenge for you 😁.
This one will be a little bit more difficult than the one in the Guess My Number project, but you can still try to do it. So, what is expected from you is to reset all the initial conditions of the game when we click on the new game button, as mentioned above.
It doesn't matter if your solution is different from mine. The most important thing here is to try and learn, and I want you to write code on your own. Whether you'll achieve the goal in the end or not is not the point right now.
So just stop scrolling and try to do it on your own.
I hope you had a great time doing that. Let's now tackle it together.
We need the below buttonNew variable we selected in one of our previous lectures, and on it, we will add an event handler.
const buttonNew = document.querySelector('.btn--new');
buttonNew.addEventListener('click', function () {
// Set total scores to zero
player0ScoreEl.textContent = 0;
player1ScoreEl.textContent = 0;
// Set current scores to zero
player0CurrentEl.textContent = 0;
player1CurrentEl.textContent = 0;
// Remove winner class
player0El.classList.remove('player--winner');
player1El.classList.remove('player--winner');
// Add winner class to player 1 and remove on player 2
player0El.classList.add('player--active');
player1El.classList.remove('player--active');
});
That's it for the visible part of the user interface. We changed classes, and we manipulated the content. We also need to set our internal state variables back to their initial state. That is, scores
, currentScore
, activePlayer
, and playing
.
const scores = [0, 0];
let currentScore = 0;
let activePlayer = 0;
let playing = true;
We can just copy the above code and add it to our new game event handler, but I guess you already know that it's not a good idea. Instead, we will create a function called initGame
which will be responsible for resetting and initializing everything.
const initGame = function () {
const scores = [0, 0];
let currentScore = 0;
let activePlayer = 0;
let playing = true;
// Set total scores to zero
player0ScoreEl.textContent = 0;
player1ScoreEl.textContent = 0;
// Set current scores to zero
player0CurrentEl.textContent = 0;
player1CurrentEl.textContent = 0;
// Remove winner class
player0El.classList.remove('player--winner');
player1El.classList.remove('player--winner');
// Hide dice
diceEl.classList.add('hidden');
// Add winner class to player 1 and remove on player 2
player0El.classList.add('player--active');
player1El.classList.remove('player--active');
};
So right now, if you save everything and go to your browser, you will see that the initial conditions that we have are the values that are written in our HTML file, and our buttons, too, aren't working.
These issues happen because our initial variables in our initGame function are not set. That's because our function cannot run on its own. And so as you might guess, the solution to that is to run our function.
// You can run it below your function expression
initGame();
Now that we've executed our initGame function, you will notice that everything is back to normal in the browser, but our buttons aren't working. If you try clicking on the roll or hold button, you will get the below error.
This error comes from something we already talked about briefly before, but we didn't go into yet. That's because, in the next section, we will get deep into something called scoping.
To make it simple, the variables we defined inside our initGame
function are only available inside that function. That is, scores
, currentScore
, activePlayer
, and playing
. In technical terms, we say that they are scoped to the initGame
function, because that is where we declared them.
And so the solution is to declare these variables outside of the initGame
function and then initialize them in the initGame
function.
Let's now declare our variables.
let scores, currentScore, activePlayer, playing;
We then need to get rid of the let
and const
keywords in our function, because that would then create new variables and that's not what we want. We want the variables to live outside of the function and then, in the initGame
function, we only initialize them.
const initGame = function () {
scores = [0, 0];
currentScore = 0;
activePlayer = 0;
playing = true;
//...
};
To finish, we also need to use our initGame
function as our new game event handler.
buttonNew.addEventListener('click', initGame);
Give it a save, and everything should now work just fine. With this last feature that we implemented, the game is ready and feature complete. Once more, I hope you're happy with what we just implemented.
With this last lecture, we finished the fundamentals part of JavaScript. See you in the next lecture, where we will start learning how JavaScript works behind the scenes.