Rock, Paper, Scissors


#1

Hello, I’m trying to figure our what is wrong with my code, but I can’t find where it’s wrong.
The task is:
Create three buttons, one for each selection. Add an event listener to the buttons that calls your playRound function with the correct playerSelection every time a button is clicked. (you can keep the console.logs for this step)
This is from my html file->

Rock Paper Scissors

This is from my JS file->
var rock = document.getElementById(‘rock’);
var paper = document.getElementById(‘paper’);
var scissors = document.getElementById(‘scissors’);
let result = 0;
let playerResult = 0;
let computerResult = 0;
function computerPlay() {
let computerSelection = [rock, paper, scissors];
let randomNumber = Math.floor(Math.random() * 3 );
return computerSelection[randomNumber];
}
function playRound(playerSelection, computerSelection){
switch(playerSelection){
case rock:
switch(computerSelection){
case rock:
result = ‘tie’;
return ‘It’s a draw’;
break;
case paper:
result = ‘lose’;
return ‘Paper beats rock! You lose!’;
break;
case scissors:
result = ‘win’;
return ‘Rock beats scissors! You win!’
break;
}
break;
case paper:
switch(computerSelection){
case rock:
result = ‘win’;
return ‘You win! Paper beats rock!’;
break;
case paper:
result = ‘tie’;
return ‘It\s a draw’;
break;
case scissors:
result = ‘lose’;
return ’ Scissors beats paper! You lose!’
break;
}
break;
case scissors:
switch(computerSelection){
case rock:
result = ‘lose’;
return ‘Rock beats scissors!You lose!’;
break;
case paper:
result = ‘win’;
return ‘Scissors beats paper!You win!’;
break;
case scissors:
result = ‘tie’;
return ‘It’s a draw’
break;
}
break;
}
}
function game() {
rounds = 5;
for(var i = 0; i < rounds; i++){
let playerSelection = document.addEventListener(“click”, playRound);
let computerSelection = computerPlay();
console.log(playRound(playerSelection, computerSelection));
if(result == ‘win’){
playerResult++;
} else if(result == ‘lose’){
computerResult++
}
console.log(“You have “+ playerResult +” points”);
console.log(“Computer has “+ computerResult +” points”);
}
(playerResult > computerResult) ? console.log(‘You have won this game!’) : console.log(“Sorry, computer was better this time!”);
computerPlay();
}
game();

Could you give me a hint where I am wrong? Thank you very much!


#2

Hey @KristianaGaizauskien

What behaviour are you actually getting?


#3

Hi, @CouchofTomato !
In console I am getting(I didn’t even pressed buttons)->
undefined rock_paper_scissors_update.js:69:21
You have 0 points rock_paper_scissors_update.js:75:21
Computer has 0 points rock_paper_scissors_update.js:76:21
undefined rock_paper_scissors_update.js:69:21
You have 0 points rock_paper_scissors_update.js:75:21
Computer has 0 points rock_paper_scissors_update.js:76:21
undefined rock_paper_scissors_update.js:69:21
You have 0 points rock_paper_scissors_update.js:75:21
Computer has 0 points rock_paper_scissors_update.js:76:21
undefined rock_paper_scissors_update.js:69:21
You have 0 points rock_paper_scissors_update.js:75:21
Computer has 0 points rock_paper_scissors_update.js:76:21
undefined rock_paper_scissors_update.js:69:21
You have 0 points rock_paper_scissors_update.js:75:21
Computer has 0 points rock_paper_scissors_update.js:76:21
Sorry, computer was better this time! rock_paper_scissors_update.js:78:92


#4

It might be easier if you get the code up in a codepen or repl so we can see it in action.


#5

Not sure if I am adding codepen correctly. But here is link to my code:
https://codepen.io/KristianaG/pen/LYYMJbg


#6

Thank you.

I have seen a few issues with your code.

let playerSelection = document.addEventListener("click", playRound);

You have this code, but that doesn’t do what you think. Here what happens when the document is clicked is it calls teh playRound function with no arguments. That’s why you keep seeing defined.

What you need to do is inside the playRound function, the event listener will pass it an argument which you can use to get the player Selection.

document.addEventListener("click", playRound)
// the playRound function here gets passed an argument that you can access by naming it in the function definition
function playRound(evt) { //evt or e is usually used meaning event
  evt.target //gets you the element that was clicked
  evt.target.textContent //gets you the text content of the element that was clicked
}

let computerSelection = computerPlay();

This code should be moved from the game function to inside playRound.

You don’t need console.log(playRound(playerSelection, computerSelection)); inside game as it’s calling the playRound function again outside of the event click.

Inside of game you also can’t use a loop. The event listener is async code which means it doesn’t stop code execution. The loop will run before anything has been clicked.

What you need to do is each time someone clicks a button you need to increase a counter by one and then when the counter reaches some limit you can then check for a winner. That means you’d need to keep count of who won each round.

Hope that gives you some ideas to move forward. Let me know if you get stuck anywhere else.


#7

@CouchofTomato I’ve tried to fix my code but still that does not work. I think now there is something with my switch statement(because I’ve made IF statement for the same situation just to try out my code and with similar IF statement it was working(“Game over” did not worked with my IF statement), but still I would like to understand what is wrong with my switch statement. I think it is something about playerResult+=1; and computerResult+=1;
I would appreciate if you could give me a hint where am I wrong!
Thank you so much for your help!
https://codepen.io/KristianaG/pen/LYYMJbg


#8

Hi Kristiana!

Good news. Your main code is actually working! There are just a couple of changes to be made.

Annotation%202019-11-20%20165638
Figure 1: Correct results after changes below are made

The problem is that your Game Over condition check is only running once and this happens when the page first loads. This is the code I’m referring to (line 78 - 86):

 if (playerResult==5 || computerResult==5 ){
      console.log("Game over!");
      rock.removeEventListener("click", playGameRock);
      paper.removeEventListener("click", playGamePaper);
      scissors.removeEventListener("click",playGameScissors);
      rock.disabled = true;
      paper.disabled = true;
      scissors.disabled = true;
  }

This code needs to be repeated after each time a person plays their hand (Rock Paper Scissors). The easiest way to do this is to put the above code in a function, like this:

function checkWinner() {
  if (playerResult==5 || computerResult==5 ){
      console.log("Game over!");
      rock.removeEventListener("click", playGameRock);
      paper.removeEventListener("click", playGamePaper);
      scissors.removeEventListener("click",playGameScissors);
      rock.disabled = true;
      paper.disabled = true;
      scissors.disabled = true;
  }
}

Then you can call this function when the player clicks a Rock, Paper or Scissors button.

But you will first need to make another change.

Here is your original code for when a person clicks ‘Rock’:

  function playGameRock(){
    return playRound("rock", computerSelection());
  }

This is where you want to now want to check your new Game Over function, but first you need to remove the return from this function as return will immediately halt everything and exit the function. You only need to simply call playRound(…), you don’t need to return it since you aren’t using anything from it. After the return is removed, you can add the checkWinner() function.

Based on what was said above, it will now look like this:

  function playGameRock(){
    playRound("rock", computerSelection());
    checkWinner();
  }

So the changes that needed to be made are:

  1. Turn your Game Over check into a function so it can be called whenever you need it.
  2. Adjust your playGameRock, playGameScissors and playGamePaper functions to exclude the return, and add a call for your checkWinner() function.

Here is a CodePen that has the above changes. I’ve console.log a lot of information that was used for debugging, please try and ignore them: https://codepen.io/Martink-rsa/pen/ZEEPGBo?editors=0010

Summary

This text will be hidden