1

I recently had an issue with a simple JS game, which I asked about here: Issue with negative scores in a simple JS game

It was fixed after I was advised to fix the else if statement. After that it worked fine.

I copied this game and swapped out the maths guessing part for a capital city guessing part, leaving everything else the same. The structure of the if/else if statements remains the same. However I am having the same issue again with the score not calculating correct, it starts increasing by more than 1x each time a question is answered.

The JS is:

//Initial values assigned
let score = 0
let countDown = 10

//Start Button Triggers this countdown function:
function startCountdown(seconds) {
  document.getElementById("start").setAttribute('disabled', '') //Disables Start button once the game starts
  let counter = seconds;
    
  const interval = setInterval(() => {
    document.getElementById("timer").innerHTML = Math.floor(counter);
    counter--;
      
    if (counter < 0 ) {
      clearInterval(interval);
      game()
      startCountdown(countDown) //this function with "countDown" argument passed in starts a new countdown
    }
  }, 1000);
}

//This function triggers a new question
function game(){
  
  //Decreases the countdown time as the score gets higher:
  if (score > 5 && score < 11){
    countDown = 10-score/2
    
  }
  
 //This block is game questions and answers:
  
  const countries = [
    {ID:1,Country:"New Zealand",Capital:"Wellington"}, 
    {ID:2,Country:"Belarus",Capital:"Minsk"}, 
    {ID:3,Country:"Japan",Capital:"Tokyo"},
    {ID:4,Country:"Philippines",Capital:"Manila"},
    {ID:5,Country:"Mongolia",Capital:"Ulaanbaatar"},
    {ID:6,Country:"Switzerland",Capital:"Bern"}


    ];
  
    let random = Math.floor(Math.random() * countries.length);
    let random2 = Math.floor(Math.random() * countries.length);
    let random3 = Math.floor(Math.random() * countries.length);

    let chosen = countries[random];
    document.getElementById("challenge").innerHTML = `What is the capital city of<b>${chosen.Country}</b> ?`
  
  
 //let answer1 = Math.floor(Math.random()*500)
 //let answer2 = Math.floor(Math.random()*500)
 //document.getElementById("challenge").innerHTML = `What is <b>${answer1}</b> plus <b>${answer2}</b>?`
     let number1 = countries[random2].Capital;
     let number2 = chosen.Capital;
     let number3 = countries[random3].Capital;
     let gameNums = [number1, number2,number3]
     shuffle(gameNums)
  document.getElementById("button1").innerHTML = gameNums[0]
  document.getElementById("button2").innerHTML = gameNums[1]
  document.getElementById("button3").innerHTML = gameNums[2]
  
  //This function determines which answer is correct and incorrect:
  function handleClick(event) {

  if (event.target.tagName !== "BUTTON") {
    return;
  }

  let buttonValue = event.target.innerText;
  
    //Correct Answer:
    if (buttonValue == number2){
      document.querySelector("#result").innerText = "Correct!";
      document.getElementById("result").style.color = "green";
      score++
      document.getElementById("score").innerHTML = `Score = ${score}`
      game()
      }
    
    //Incorrect Answer:
    else if(buttonValue == number1 || buttonValue == number3){
       document.querySelector("#result").innerText = "Incorrect!";
       document.getElementById("result").style.color = "red";
       score--
          //This stops the score going below zero:
          if (score < 0){
          score = 0
          }
      document.getElementById("score").innerHTML = `Score = ${score}`
      game()
       }
    
    
}
  

//Listens for button clicks
document.querySelector(".buttons").addEventListener("click", handleClick);

}
  

//function for shuffling the array

function shuffle(array) {
  let currentIndex = array.length,  randomIndex;

  // While there remain elements to shuffle...
  while (currentIndex != 0) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex--;

    // And swap it with the current element.
    [array[currentIndex], array[randomIndex]] = [
      array[randomIndex], array[currentIndex]];
  }

  return array;
}

Codepen: https://codepen.io/tmnsoon/pen/yLpOmeX?editors=1010

Not sure why this is?

Thanks!

tmnsoon
  • 15
  • 4

1 Answers1

2

The problem is you keeping assigning the eventListener to the document.querySelector(".buttons") which cause problems.

Every time you trigger the game function, you will assign a new eventListener to .buttons which makes your every time you click the .button, you will trigger the game function for not only one time which makes the score doesn't work as you expected.

You could use Chrome developer tool to check that (if you are using chrome)


getEventListeners(document.querySelector('.buttons'));

and you will find that after severel click to the buttons, the eventListener for buttons will be more than 1.

Example:?enter image description here

Now the button have 190 eventListener which means every time it click, it will trigger the function for 190 times.

Solution:

I remove the handleClicker to outside the function and declare the number1,number2,number3 outside the function to make it global.

let score = 0
let countDown = 10
let number1,number2,number3;

//Start Button Triggers this countdown function:
function startCountdown(seconds) {
  document.getElementById("start").setAttribute('disabled', '') //Disables Start button once the game starts
  let counter = seconds;
    
  const interval = setInterval(() => {
    document.getElementById("timer").innerHTML = Math.floor(counter);
    counter--;
      
    if (counter < 0 ) {
      clearInterval(interval);
      game()
      startCountdown(countDown) //this function with "countDown" argument passed in starts a new countdown
    }
  }, 1000);
}

//This function triggers a new question
function game(){
console.log('hi')
  //Decreases the countdown time as the score gets higher:
  if (score > 5 && score < 11){
    countDown = 10-score/2
    
  }
  
 //This block is game questions and answers:
  
  const countries = [
    {ID:1,Country:"New Zealand",Capital:"Wellington"}, 
    {ID:2,Country:"Belarus",Capital:"Minsk"}, 
    {ID:3,Country:"Japan",Capital:"Tokyo"},
    {ID:4,Country:"Philippines",Capital:"Manila"},
    {ID:5,Country:"Mongolia",Capital:"Ulaanbaatar"},
    {ID:6,Country:"Switzerland",Capital:"Bern"}


    ];
  
    let random = Math.floor(Math.random() * countries.length);
    let random2 = Math.floor(Math.random() * countries.length);
    let random3 = Math.floor(Math.random() * countries.length);

    let chosen = countries[random];
    document.getElementById("challenge").innerHTML = `What is the capital city of<b>${chosen.Country}</b> ?`
  
  
     number1 = countries[random2].Capital;
     number2 = chosen.Capital;
      number3 = countries[random3].Capital;
     let gameNums = [number1, number2,number3]
     shuffle(gameNums)
  document.getElementById("button1").innerHTML = gameNums[0]
  document.getElementById("button2").innerHTML = gameNums[1]
  document.getElementById("button3").innerHTML = gameNums[2]
  
  //This function determines which answer is correct and incorrect:
 
  

//Listens for button clicks
}
  

 function handleClick(event) {

  if (event.target.tagName !== "BUTTON") {
    return;
  }

  let buttonValue = event.target.innerText;
  
    //Correct Answer:
    if (buttonValue == number2){
      document.querySelector("#result").innerText = "Correct!";
      document.getElementById("result").style.color = "green";
      score++
      document.getElementById("score").innerHTML = `Score = ${score}`
      game()
      }
    
    //Incorrect Answer:
    else if(buttonValue == number1 || buttonValue == number3){
       document.querySelector("#result").innerText = "Incorrect!";
       document.getElementById("result").style.color = "red";
       score--
          //This stops the score going below zero:
          if (score < 0){
          score = 0
          }
      document.getElementById("score").innerHTML = `Score = ${score}`
      game()
       }
    
    
}
document.querySelector(".buttons").addEventListener("click",
    handleClick);
//function for shuffling the array

function shuffle(array) {
  let currentIndex = array.length,  randomIndex;

  // While there remain elements to shuffle...
  while (currentIndex != 0) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex--;

    // And swap it with the current element.
    [array[currentIndex], array[randomIndex]] = [
      array[randomIndex], array[currentIndex]];
  }

  return array;
}
<div class="wrapper">
  <h1>Maths Adding Game</h1>
  <button id="start" onclick="startCountdown(0)">Start</button>
  <br>
  <span id="timer"></span>
  <br>
  <div id="challenge"></div>
  <br>
  <div class="buttons">
    <button type="button" id="button1">???</button>
    <button type="button" id="button2">???</button>
    <button type="button" id="button3">???</button>
    
   
  </div>
  <div id="score">Score = Zero</div>
  <div class="result">Result: <span id="result">N/A</span></div>
</div>
James
  • 2,732
  • 2
  • 5
  • 28