skip to Main Content

I am attempting to create a rock-paper-scissors game. My code runs 3 times when I click on the image once and then stops. I worked perfectly once and then started this issue. Any assistance would be helpful. I have double-checked and the classes are correct. I have very little HTML or CSS and have not messed with it. I had a while loop that governed how long the game would be played but that did not work well once I created the DOM events.

//Begins function of actual RPS game

let Humanity = 0;
let AI = 0;

//Create function to generate random computer choice

function getComputerChoice() { 

    const choices = ['rock', 'paper', 'scissors'];
    const randomChoice = Math.floor(Math.random() * choices.length);
    const decision = choices[randomChoice];
    return decision;

 } getComputerChoice();

 //Allows game to run each time picture is clicked on

 let paper = document.querySelector('.paper')
 this.addEventListener('click', handlePaper)

 let rock = document.querySelector('.rocks')
 this.addEventListener('click', handleRock)

 let scissors = document.querySelector('.scissors')
 this.addEventListener('click', handleScissors)

 //Allows game to not automatically run forever because at each click event listener is removed

 function handlePaper() {
    round('paper');
    this.removeEventListener('click', handlePaper);
 }

 function handleRock() {
    round('rock');
    this.removeEventListener('click', handleRock);
 }

 function handleScissors() {
    round('scissors');
    this.removeEventListener('click', handleScissors);
 }

//play a round of game

 function round(playerDecision) {

    let computerChoice = getComputerChoice();

    if (playerDecision === 'rock' && computerChoice === 'scissors') {
        Humanity += 1;
        alert('Humanity wins' + ' ' + 'your score is' + ' ' + Humanity);
    } else if (playerDecision === 'scissors' && computerChoice === 'paper') {
        Humanity += 1;
        alert('Humanity wins' + ' ' + 'your score is' + ' ' + Humanity);
    } else if (playerDecision === 'paper' && computerChoice === 'rock') {
        Humanity += 1;
        alert('Humanity wins' + ' ' + 'your score is' + ' ' + Humanity);
    } else if (playerDecision === 'rock' && computerChoice === 'paper') {
        AI += 1;
        alert('AI wins' + ' ' + 'AIs score is' + ' ' + AI);
    } else if (playerDecision === 'scissors' && computerChoice === 'rock') {
        AI += 1;
        alert('AI wins' + ' ' + 'AIs score is' + ' ' + AI);
    } else if (playerDecision === 'paper' && computerChoice === 'scissors') {
        AI += 1;
        alert('AI wins' + ' ' + 'AIs score is' + ' ' + AI);
    } else if (playerDecision === computerChoice) {
        alert('It is a tie' + ' ' + 'the score is' + ' ' + 'AI' + ' ' + AI + ' ' + 'Humanity' + ' ' + Humanity );
    } else if (Humanity === 5 || AI === 5) {
        endGame();
    }
    
  } round();

 //Play game until one user gets to 5

 function endGame() {

    if (Humanity >= 5) {
        alert('Game over, Humanity is saved!')
    } else if (AI >= 5) {
        alert('Game over, Humanity is doomed!')
    }

  } endGame();

2

Answers


  1. You are doing a few strange things in your code which I will try to explain and correct below.

    you don’t need to call getComputerChoice() immediately after creating that function. You call it when you call round() which happens when a button is clicked. I’ve commented this function call out.

    You are selecting elements, and then not using those saved variables. Instead you are calling this.* afterwards, which is nothing. this will refer to the current context, like the window in a browser, or the function you are running inside of. You seem to be using it as if it refers to the most recently created variable or something like that. You just need to use your variables.

    You do not need to remove the event listeners. If you want each button in the game to be clicked more than once, then you should just keep the event listeners on there so you can keep listening for clicks. You seem to want to get to 5 rounds, so this will allow you to get there. I’ve commented these out.

    You are calling the endGame() function immediately when the game starts. Why? The game hasn’t event started yet? I’ve commented this out.

    When you are creating strings for the alert messages you are adding a space as a separate string for some reason.

    "Humanity wins" + " " + "your score is" + " " + Humanity`
    

    is exactly the same as writing

    "Humanity wins " + "your score is " + Humanity
    

    Just type the space with the previous string, you don’t need to make then separate and then add them together. That’s just more work for you.


    Below is a functional game with the fixes I mentioned.

    //Begins function of actual RPS game
    
    let Humanity = 0;
    let AI = 0;
    
    //Create function to generate random computer choice
    
    function getComputerChoice() {
      const choices = ["rock", "paper", "scissors"];
      const randomChoice = Math.floor(Math.random() * choices.length);
      const decision = choices[randomChoice];
      return decision;
    }
    //getComputerChoice();
    
    //Allows game to run each time picture is clicked on
    
    let paper = document.querySelector(".paper");
    paper.addEventListener("click", handlePaper);
    
    let rock = document.querySelector(".rock");
    rock.addEventListener("click", handleRock);
    
    let scissors = document.querySelector(".scissors");
    scissors.addEventListener("click", handleScissors);
    
    //Allows game to not automatically run forever because at each click event listener is removed
    
    function handlePaper() {
      round("paper");
      //paper.removeEventListener("click", handlePaper);
    }
    
    function handleRock() {
      round("rock");
      //rock.removeEventListener("click", handleRock);
    }
    
    function handleScissors() {
      round("scissors");
      //scissors.removeEventListener("click", handleScissors);
    }
    
    //play a round of game
    
    function round(playerDecision) {
      let computerChoice = getComputerChoice();
    
      if (playerDecision === "rock" && computerChoice === "scissors") {
        Humanity += 1;
        alert("Humanity wins " + "your score is " + Humanity);
      } else if (playerDecision === "scissors" && computerChoice === "paper") {
        Humanity += 1;
        alert("Humanity wins " + "your score is " + Humanity);
      } else if (playerDecision === "paper" && computerChoice === "rock") {
        Humanity += 1;
        alert("Humanity wins " + "your score is " + Humanity);
      } else if (playerDecision === "rock" && computerChoice === "paper") {
        AI += 1;
        alert("AI wins " + "AIs score is " + AI);
      } else if (playerDecision === "scissors" && computerChoice === "rock") {
        AI += 1;
        alert("AI wins " + "AIs score is " + AI);
      } else if (playerDecision === "paper" && computerChoice === "scissors") {
        AI += 1;
        alert("AI wins " + "AIs score is " + AI);
      } else if (playerDecision === computerChoice) {
        alert("It is a tie " + "the score is " +"AI " +AI +" Humanity " +Humanity);
      } else if (Humanity === 5 || AI === 5) {
        endGame();
      }
    }
    round();
    
    //Play game until one user gets to 5
    
    function endGame() {
      if (Humanity >= 5) {
        alert("Game over, Humanity is saved!");
      } else if (AI >= 5) {
        alert("Game over, Humanity is doomed!");
      }
    }
    //endGame();
    <button type="button" class="paper">paper</button>
    <button type="button" class="rock">rock</button>
    <button type="button" class="scissors">scissors</button>

    If I were to re-write you code to be a bit simpler and easier to work with, here’s how I’d change it:

    //Define variables
    const maxRounds = 5;
    let scoreHuman = 0;
    let scoreComputer = 0;
    //----------------------------------------
    
    
    
    //----------------------------------------
    //Define functions
    function getComputerChoice() {
      const choices = ["rock", "paper", "scissors"];
      const randomChoice = Math.floor(Math.random() * choices.length);
      return choices[randomChoice];
    }
    
    function getScoreMessage() {
      return "The score is:n  AI: " + scoreComputer + "n  Humanity: " + scoreHuman;
    }
    
    function round(playerDecision) {
      let computerChoice = getComputerChoice();
    
      const playerWins =
        (playerDecision === "rock" && computerChoice === "scissors") ||
        (playerDecision === "scissors" && computerChoice === "paper") ||
        (playerDecision === "paper" && computerChoice === "rock");
    
      const computerWins =
        (playerDecision === "rock" && computerChoice === "paper") ||
        (playerDecision === "scissors" && computerChoice === "rock") ||
        (playerDecision === "paper" && computerChoice === "scissors");
    
      if (scoreHuman === maxRounds || scoreComputer === maxRounds) {
        //Check this first
        endGame();
      } else if (playerWins) {
        scoreHuman++;
        alert("Humanity wins! " + getScoreMessage());
      } else if (computerWins) {
        scoreComputer++;
        alert("AI wins! " + getScoreMessage());
      } else if (playerDecision === computerChoice) {
        alert("It is a tie! " + getScoreMessage());
      }
    }
    
    function endGame() {
      let word = '';
      if (scoreHuman >= maxRounds) {
        word = "saved";
      } else if (scoreComputer >= maxRounds) {
        word = "doomed";
      }
      alert("Game over, Humanity is " + word + "!");
    }
    //----------------------------------------
    
    
    
    //----------------------------------------
    //Define click handlers to interact with the game
    document.querySelector(".paper").addEventListener("click", function () {
      round("paper");
    });
    document.querySelector(".rock").addEventListener("click", function () {
      round("rock");
    });
    document.querySelector(".scissors").addEventListener("click", function () {
      round("scissors");
    });
    <button type="button" class="paper">paper</button>
    <button type="button" class="rock">rock</button>
    <button type="button" class="scissors">scissors</button>
    Login or Signup to reply.
  2. The reason why your code runs 3 times when you click on the image once is that you are using the addEventListener() method to add a click event listener to each of the image elements. The addEventListener() method takes two arguments: the first is the event type, and the second is the function that will be called when the event occurs. In your code, you are passing the click event type as the first argument, and you are passing a different function as the second argument for each image element. This means that when you click on an image, all three functions will be called.
    To fix this, you can use the querySelectorAll() method to get a reference to all of the image elements, and then you can use the forEach() method to loop through the image elements and add a single click event listener to each of them. The following code shows how to do this:

    // Get a reference to all of the image elements
    const imageElements = document.querySelectorAll('img');
    
    // Loop through the image elements and add a click event listener to each of them
    imageElements.forEach(imageElement => {
      imageElement.addEventListener('click', handleClick);
    });
    
    // Define the handleClick function
    function handleClick() {
      // Get the player's choice
      const playerChoice = document.querySelector('input[name="choice"]:checked').value;
    
      // Get the computer's choice
      const computerChoice = getComputerChoice();
    
      // Compare the player's choice to the computer's choice and determine the winner
      if (playerChoice === computerChoice) {
        alert('It is a tie!');
      } else if (playerChoice === 'rock' && computerChoice === 'scissors') {
        alert('Humanity wins!');
      } else if (playerChoice === 'scissors' && computerChoice === 'paper') {
        alert('Humanity wins!');
      } else if (playerChoice === 'paper' && computerChoice === 'rock') {
        alert('Humanity wins!');
      } else if (playerChoice === 'rock' && computerChoice === 'paper') {
        alert('AI wins!');
      } else if (playerChoice === 'scissors' && computerChoice === 'rock') {
        alert('AI wins!');
      } else if (playerChoice === 'paper' && computerChoice === 'scissors') {
        alert('AI wins!');
      }
    }
    

    This code will only call the handleClick() function once when you click on an image.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search