Дальнейшие проблемы с очками в простой игре JS

Недавно у меня возникла проблема с простой игрой JS, о которой я спрашивал здесь: Проблема с отрицательными оценками в простой игре JS

Это было исправлено после того, как мне посоветовали исправить оператор else if. После этого он работал нормально.

Я скопировал эту игру и заменил часть с угадыванием математики на часть с угадыванием столицы, оставив все остальное без изменений. Структура операторов if/else if остается прежней. Однако у меня снова возникает та же проблема, когда оценка не рассчитывается правильно, она начинает увеличиваться более чем в 1 раз каждый раз, когда на вопрос дается ответ.

JS это:

//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;
}

Кодовое слово: https://codepen.io/tmnsoon/pen/yLpOmeX?editors=1010

Не уверен, почему это?

Спасибо!

Пожалуйста, не используйте внешние ссылки для обмена простым кодом, вы можете использовать фрагмент кода SO для базового кода HTML, CSS и JS.

EzioMercer 20.03.2022 04:53

если (оценка > 0) { оценка --}

webCatDev 20.03.2022 04:54

@webCatDev, это не вызывает проблемы, потому что код OP использует Math.floor для оценки, поэтому, когда socre больше 0, он будет 1,2 ...

James 20.03.2022 05:18
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
38
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что вы продолжаете назначать прослушиватель событий document.querySelector(".buttons"), что вызывает проблемы.

Каждый раз, когда вы запускаете функцию game, вы назначаете новый eventListener для .buttons, что делает каждый раз, когда вы нажимаете .button, вы запускаете игровую функцию не только один раз, из-за чего счет не работает так, как вы ожидали.

Вы можете использовать инструмент разработчика Chrome, чтобы проверить это (если вы используете Chrome)


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

и вы обнаружите, что после сильного нажатия кнопок eventListener для buttons будет больше 1.

Пример:?

Теперь у button есть 190 прослушивателей событий, что означает, что каждый раз, когда он щелкает, он будет запускать функцию 190 раз.

Решение:

Я удаляю handleClicker за пределы функции и объявляю number1,number2,number3 вне функции, чтобы сделать ее глобальной.

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.info('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>

Другие вопросы по теме