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
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 callround()
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 thewindow
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.
is exactly the same as writing
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.
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:
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. TheaddEventListener()
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 theforEach()
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:This code will only call the
handleClick()
function once when you click on an image.