[SOLVED] Can't figure out Rock, Paper, Scissors project


#1

I’m really out of my element with this one, I’ve read through all the fundamentals twice in a week now and I still don’t get how my code should look like at all…

Edit: I’ve been doing some fiddling and looking at other people’s solution (which I don’t get still…) and now I’m wondering why my code returns undefined here(SOLUTION BY CouchofTomato: call function Math.round(Math.random()*3 in computerPlay)

EDIT 2: Now the problem I have is that the initial prompt appears but whenever I enter anything none of the alerts show(SOLVED: See Edit 3):

EDIT 3: Make code more readable (for me at least), nothing appears on the console.log(SOLVED: remove computerSelection variable from the switch function as it gives an ‘uninitialized variable error’:

EDIT 4: Alerts appear sometimes but mostly doesn’t show anything after prompt.

EDIT 5: Took a look at other solutions and noticed that their switch functions started with 0(Is that the general rule?) Alerts appear more frequently now when prompted, but still don’t appear as much as I like. (SOLVED: Didn’t set up a else if clause that covered whenever the choices would be tied.)

EDIT 6: FINAL FULL WORKING CODE:

   function computerPlay() {
          let answer = Math.floor(Math.random()*3);

          switch (answer){
              case 0:
              return 'rock';
              break;

              case 1: 
              return 'paper';
              break;

              case 2: 
              return 'scissors';
              break;
            }
    }
        // One round played
        function oneRound(playerSelection, computerSelection) {
  
          if (playerSelection == 'rock' && computerSelection == 'paper'){
            alert("You lose! Paper beats rock!")
            
            } else if (playerSelection == 'paper' && computerSelection == 'rock') {
                alert('You win! Paper beats rock!')
              
            } else if (playerSelection == 'paper' && computerSelection == 'scissors'){
                alert("You lose! Scissors beat paper!")
              
            } else if (playerSelection == 'scissors' && computerSelection == 'paper'){
                alert('You win! Scissors beat paper!')
              
            } else if (playerSelection == 'scissors' && computerSelection == 'rock'){
                alert("You lose! Rock beats Scissors!")
              
            } else if (playerSelection == 'rock' && computerSelection == 'scissors'){
                alert("You win! Rock beats paper!")
              
            } else if (playerSelection == ''){
                alert("Let's play next time.")
              / / Alert when the game is a tie
            }else if (playerSelection == computerSelection) {
            alert("It's a tie!")
           / / Inputs anything besides 'rock', 'paper' or 'scissors'
            } else {
              alert("Input again.")
            }
        }
        let playerSelection = prompt('Rock, Paper, Scissors?').toLowerCase();
        const computerSelection = computerPlay();
        oneRound(playerSelection, computerSelection);

Thanks to CouchofTomato for all the help with troubleshooting


#2

Hi @Nathanielle,

You aren’t far away at all. The issue here is Math.random is a function so if you don’t invoke it with () then it just returns a reference to that function. Therefore what is getting assigned to the answer variable is NaN.

What you need to do is call the function so Math.random() * 3.

The other issue is that this will return a decimal float so it won’t match against any of the switch cases. You probably want convert it to an integer with Math.round or similar.

Let us know if you hit any more problems.


#3

Hello, thanks for the explanation!

I’ll keep fiddling with my code but now it looks like the alerts won’t even show up no matter what the player inputs, probably how my if…else is structured?


#4

Maybe ensure you convert the player input to lowercase or something?


#5

I’ve added the lower case function like so:

const playerSelection = prompt('Rock, Paper, Scissors?').toLowerCase();
const computerSelection = computerPlay();

But nothing works past the initial prompt.


#6

Are you calling the oneRound function?

Did you also address the issue with the computerPlay function?


#8

Code works now! (Kind of)

Sometimes the alert appears, most of the time it doesn’t :tired_face:

It kinda looks like the {if…else statements} cancel each other out whenever I try to replay the round


#9

What do you mean cancel each other out?


#10

I’ve noticed that whenever I choose ‘rock’ it works all the time, I refresh the page and choose ‘paper’ or ‘scissors’ no alert shows up.


#11

If you refresh the page and choose rock what happens?


#13

The alert for ‘rock’ show up as intended


#14

Try adding a default else clause in the playRound function to see if it shows up when scissors or paper gets chosen.


#15

Added this to the end of my oneRound();

} else (playerSelection == 'paper' || playerSelection == 'scissors')
 alert('You picked paper/scissors!')

This is the only thing that shows up whenever paper/scissors are chosen after choosing rock.
Noticed that it also showed up when choosing rock but its first alerts still show up


#16

Can you please post your full code as it currently is?


#18

Here’s the updated code with the default else clause:

 function computerPlay() {
      let answer = Math.round(Math.random()*3);

      switch (answer){
          case 0:
          return 'rock';
          break;

          case 1: 
          return 'paper';
          break;

          case 2: 
          return 'scissors';
          break;
        }
}
    // One round played
    function oneRound(playerSelection, computerSelection) {

      if (playerSelection == 'rock' && computerSelection == 'paper'){
        alert("You lose! Paper beats rock!")
        
        } else if (playerSelection == 'paper' && computerSelection == 'rock') {
            alert('You win! Paper beats rock!')
          
        } else if (playerSelection == 'paper' && computerSelection == 'scissors'){
            alert("You lose! Scissors beat paper!")
          
        } else if (playerSelection == 'scissors' && computerSelection == 'paper'){
            alert('You win! Scissors beat paper!')
          
        } else if (playerSelection == 'scissors' && computerSelection == 'rock'){
            alert("You lose! Rock beats Scissors!")
          
        } else if (playerSelection == 'rock' && computerSelection == 'scissors'){
            alert("You win! Rock beats paper!")
          
        } else if (playerSelection == ''){
            alert("Let's play next time.")
       }else (playerSelection == 'paper' || playerSelection == 'scissors') {
           alert('You picked paper/scissors!')
       }
    }
    let playerSelection = prompt('Rock, Paper, Scissors?').toLowerCase();
    const computerSelection = computerPlay();
    oneRound(playerSelection, computerSelection);

#19

There are a couple of changes to make.

In the computerPlay function change Math.round to Math.floor.

By rounding you will occasionally get 3 as answer which won’t match and the function will return undefined. By using Math.floor you will ensure it is always 0, 1 or 2

In the oneRound function the else clause shouldn’t have a condition. So it should just be

else {
  alert('You picked paper/scissors!')
}

Try that and see how you get on.


#21

This was interesting. Whenever I choose ‘paper’ it only ever answers with the default else clause, and whenever I choose ‘scissors’ the default else clause appears every 3 turns of choosing scissors. I wonder why’s that?


#22

Yeah the issue is that your clauses don’t cover all the cases. For example the event of a draw.

If you console.log the player and computer selection inside the oneRound function you’ll see what they were and then you can trace that to the alert that gets triggered and see why that happened.


#23

That makes so much sense! So the times where the alerts don’t show up means that they probably end up in a draw. I’ll update my code rn


#24

Thanks for being patient throughout all this! I’ve learned a lot with this project and your tips helped motivate me in finishing the project while also being satisfied with it.