So i did a exercise on Udemy that requires me to create a score keeper application.
- "Playing to : 5" indicates the winning score
- The input field changes the winning score
- The player 1 button increases the score on the left. When it reaches the winning score, the value changes to green and the game is over.
- The player 2 button increases the score on the right. When it reaches the winning score, the value changes to green and the game is over.
- Reset button resets the game and starts from 0 for both players.
- If the winning scored is changed halfway during a game (i.e. the scores are not 0), the scores will be reset to 0 and the "playing to:" value will change according to what was typed in the input field.
THE PROBLEM: I created a function declaration (called incremenet() )that will be able to perform the similar task of increasing the scores of player 1 and player 2. It takes in 1 argument, which would be the score of the player (p1Score or p2Score).
I tried this function on player 1 but the score does not go past 1!
I suspect that this has something to do with the scopes or hoisting/execution stacks. Using console.log, p1Score never updates. It is always 0. Hence p1ScoreDisplay is always going to be 1
On top of that, i notice that an error will also occur when p1Score reaches the winning score. To make the score increase past 1, i just placed "p1Score++" before the increment() function call in the event listener. It will state "scoreToIncrement.classList" is undefined. This should add a class of ".winner" to the score. I believe this has something to do with scoping or hoisting as well.
My understanding is that since this increment function is nested within the event listener anonymous function, the increment function should still be able to call the global variable I have declared at the beginning and update them accordingly after the function is executed. But i guess my understanding is not 100% right here.
Hopefully someone can further explain the error and correct my understanding here. Thanks! Will try to continue troubleshooting and read up (not sure if closures have anything to do with it).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Score Keeper</title>
<style>
.winner {
color: green;
}
</style>
<body>
<h1><span id="h1p1Score">0</span> to <span id="h1p2Score">0</span></h1>
<p>Playing to: <span id="winningScore">5</span></p>
<input type="number" id="inputNum" placeholder="enter max playing number">
<button id="P1">Player One</button>
<button id="P2">Player Two</button>
<button id="Reset">Reset</button>
<script src="scoreKeeper.js"></script>
</body>
</html>
Below here is the javascript
var p1Button = document.querySelector("#P1");
var p2Button = document.querySelector("#P2");
var resetButton = document.querySelector("#Reset");
var p1ScoreDisplay = document.querySelector("#h1p1Score");
var p2ScoreDisplay = document.querySelector("#h1p2Score");
var inputValue = document.querySelector("#inputNum");
var p1Score = 0;
var p2Score = 0;
var gameOver = false;
var winningScore = 5;
var displayWinningScore = document.querySelector("#winningScore");
function increment(scoreToIncrement,scoreDisplay) {
if (!gameOver) {
scoreToIncrement++;
if (scoreToIncrement === winningScore) {
scoreToIncrement.classList.add("winner");
gameOver = true;
}
scoreDisplay.textContent = scoreToIncrement;
}
}
p1Button.addEventListener("click", function () {
increment(p1Score);
/* This is the original code i have commented out and replaced with the increment function above
if (!gameOver) {
p1Score++;
if (p1Score === winningScore) {
console.log("Game Over!");
p1ScoreDisplay.classList.add("winner");
gameOver = true;
}
p1ScoreDisplay.textContent = p1Score;
}
*/
});
p2Button.addEventListener("click", function () {
/*Same function as the one above but using variables related to player 2 instead*/
if (!gameOver) {
p2Score++;
if (p2Score === winningScore) {
console.log("Game Over!");
p2ScoreDisplay.classList.add("winner");
gameOver = true;
}
p2ScoreDisplay.textContent = p2Score;
}
});
function reset() {
p1Score = 0;
p1ScoreDisplay.textContent = p1Score;
p1ScoreDisplay.classList.remove("winner");
p2Score = 0;
p2ScoreDisplay.textContent = p2Score;
p2ScoreDisplay.classList.remove("winner");
gameOver = false;
inputValue.value = "";
}
resetButton.addEventListener("click", reset);
inputValue.addEventListener("change", function () {
winningScore = Number(this.value);
displayWinningScore.textContent = this.value;
reset();
});