Rock-Paper-Scissors

Hello World!

I am having some issues with my Rock Paper Scissors game. Specifically, the console.log of the winner is not changing when it. For example, if user throws paper and computer throws scissors, I get the message of ‘User Wins!’ when it should be 'Computer wins.

I think the problem is with determineWinner(), but am not sure what’s off. Any clues would be appreciated.

console.log("hi"); const getUserChoice = (userInput) => { userInput = userInput.toLowerCase(); if ( userInput === "rock" || userInput === "paper" || userInput === "scissors" ) { return userInput; } else { console.log("Error"); } }; const getComputerChoice = () => { const randomNumber = Math.floor(Math.random() * 3); switch (randomNumber) { case 0: return "Rock"; case 1: return "Paper"; case 2: return "Scissors"; } };const determineWinner = (userChoice, computerChoice) => { if (userChoice === computerChoice) { return "Tie"; } if (userChoice === "rock") { if (computerChoice === "paper") { return "Computer wins"; } else { return "User Wins!!!"; } } if (userChoice === "paper") { if (computerChoice === "scissors") { return "Computer wins"; } else { return "User Wins!!!"; } if (userChoice === "scissors") { if (computerChoice === "rock") { return "Computer wins"; } else { return "User Wins!!!"; } } } }; const playGame = () => { const userChoice = getUserChoice("paper"); const computerChoice = getComputerChoice(); console.log(`You threw ${userChoice}`); console.log("Computer threw: " + computerChoice); console.log(determineWinner(userChoice, computerChoice)); }; playGame();

I think you have a } in the wrong place in the determineWinner function,
which caused the if (userChoice === "scissors") block to be inside the if (userChoice === "paper") block.

const determineWinner = (userChoice, computerChoice) => {
  if (userChoice === computerChoice) {
    return "Tie";
  }
  if (userChoice === "rock") {
    if (computerChoice === "paper") {
      return "Computer wins";
    } else {
      return "User Wins!!!";
    }
  }
  if (userChoice === "paper") {
    if (computerChoice === "scissors") {
      return "Computer wins";
    } else {
      return "User Wins!!!";
    }
   // } is missing here
    if (userChoice === "scissors") {
      if (computerChoice === "rock") {
        return "Computer wins";
      } else {
        return "User Wins!!!";
      }
    } // this } should not be here
  }
};
2 Likes

Hello Everyone!

I’m having a similar issue here, with this project. I run the game, and it always show the same result, no matter how many times I refresh it.

What am I doing wrong? Please help me!

https://www.codecademy.com/workspaces/63f80ffb10e4c3f9c958edf4 (link to the code)

Code:

console.log(‘hi’);
const getUserChoice = (userInput) => {
userInput = userInput.toLowerCase();
if (userInput === ‘rock’ || userInput ===‘scissors’ || userInput === ‘paper’) {
return userInput
} else {
return "${userInput}" is not a valid option. Please type "rock", "paper" or "scissors".
}
}

const getComputerChoice = () => {
let randomNumber = Math.floor(Math.random() * 3)
if (randomNumber === 0) {
return ‘rock’
} else if (randomNumber === 1) {
return ‘paper’
} else {
return ‘scissors’
}
}

const determineWinner = (userChoice, computerChoice) => {
if (userChoice === computerChoice) {
return ‘The game is a tie.’;
}
if (userChoice === ‘rock’ && computerChoice === ‘paper’) {
return ‘Sorry, but you lost. =(’
} else {
return ‘Congratulations! You won!’
}
if (userChoice === ‘paper’ && computerChoice === ‘scissors’) {
return ‘Sorry, but you lost. =(’
} else {
return ‘Congratulations! You won!’
}

if (userChoice === ‘scissors’ && computerChoice === ‘rock’) {
return ‘Sorry, but you lost. =(’
} else {
return ‘Congratulations! You won!’
}
};

const playGame = () => {
const userChoice = getUserChoice(‘paper’);
const computerChoice = getComputerChoice();
console.log(You threw ${userChoice});
console.log(Computer threw ${computerChoice});
determineWinner(userChoice, computerChoice);
console.log(determineWinner());
};
console.log(playGame());

For formatting code in forum posts, see [How to] Format code in posts

Here are a few issues to consider:

  • You wrote:
determineWinner(userChoice, computerChoice);
console.log(determineWinner());

You pass arguments to the determineWinner function, but then don’t do anything with the returned string. You should either assign the returned string to a variable OR just print the returned string immediately without assigning it to a variable. In its current form, you aren’t doing anything meaningful with the returned string. You are just discarding it. In the next statement i.e. console.log(determineWinner());, you are making a fresh function call with no arguments which causes undefined to be assigned to both parameters of the determineWinner function. You can do:

// Save returned string to a variable
let result = determineWinner(userChoice, computerChoice);
console.log(result);

// OR

// Print it directly without assigning to a variable
console.log(determineWinner(userChoice, computerChoice));
  • Since, the playGame function prints the result to the console instead of returning it, so consider changing:
// You wrote:
console.log(playGame());

// Change it to:
playGame();
  • In its current form, your program doesn’t function as intended. You wrote:
if (userChoice === computerChoice) {
    return 'The game is a tie.';
}
 
if (userChoice === 'rock' && computerChoice === 'paper') {
    return 'Sorry, but you lost. =('
} else {
    return 'Congratulations! You won!'
}

if (userChoice === 'paper' && computerChoice === 'scissors') {

Suppose userChoice is 'paper', you won’t reach the correct block. If userChoice is 'paper' and computerChoice is 'paper', then you will return 'The game is a tie.' which is correct. But, if userChoice is 'paper' and computerChoice is something other than 'paper', your program will always return 'Congratulations! You won!'
That is because

if (userChoice === 'rock' && computerChoice === 'paper') {

will evaluate as false and then you will return the string from the else block.
Instead, there are a couple of ways you can rectify this.
One Approach:

if (userChoice === computerChoice) {
    return 'The game is a tie.';
}
 
if (userChoice === 'rock' && computerChoice === 'paper') {
    return 'Sorry, but you lost. =('
} else if (userChoice === 'rock' && computerChoice === 'scissors') {
    return 'Congratulations! You won!'
}

if (userChoice === 'paper' && computerChoice === 'scissors') {

Another Approach:

if (userChoice === computerChoice) {
    return 'The game is a tie.';
}
 
if (userChoice === 'rock') {
    if (computerChoice === 'paper') {
        return 'Sorry, but you lost. =('
    } else {
       return 'Congratulations! You won!'
   }
}

if (userChoice === 'paper') {
    if (computerChoice === 'scissors') {
    // ...
1 Like

Thank you so so much! I’ve spent aaages trying to fix this!

And thanks for teaching me how to format code in posts as well :star_struck:

1 Like

Hi all, I have another (I think) similar issue. My final playGame() returns the result of who threw what correctly, but for determineWinner() it gives me “undefined” every time. When I run console.log(determineWinner('rock', 'scissors')) at the end of that block to test it, it works with all the different variations, so I don’t think the problem is in the syntax there, but I don’t know where else it could be! I watched the video and I still can’t figure out where I’ve gone wrong. Putting the whole dang thing in here because Idk where the problem is. Thanks for any help!

const getUserChoice = (userInput) => {
  userInput = userInput.toLowerCase();
  if (
    userInput === 'rock' ||
    userInput === 'paper' ||
    userInput === 'scissors'
  ) {
    return 'You chose ' + userInput;
  } else {
    console.log('Error');
  }
};

const getComputerChoice = () => {
  const randomNumber = Math.floor(Math.random() * 3);
  switch (randomNumber) {
    case 0:
      return 'computer chose rock.';
    case 1:
      return 'computer chose paper.';
    case 2:
      return 'computer chose scissors.';
  }
};

const determineWinner = (userChoice, computerChoice) => {
  if (userChoice === computerChoice) {
    return 'This game is tie';
  }
  if (userChoice === 'rock') {
    if (computerChoice === 'paper') {
      return 'Computer wins!';
    } else {
      return 'You win!';
    }
  }
  if (userChoice === 'paper') {
    if (computerChoice === 'scissors') {
      return 'Computer wins!';
    } else {
      return 'You win!';
    }
  }

  if (userChoice === 'scissors') {
    if (computerChoice === 'rock') {
      return 'Computer wins!';
    } else {
      return 'You win!';
    }
  }
};

const playGame = () => {
  const userChoice = getUserChoice('rock');
  const computerChoice = getComputerChoice();
  console.log(userChoice + ', ' + computerChoice);
  console.log(determineWinner(userChoice, computerChoice));
};

playGame();

If it truly is, ‘every time’, then there must be an edge case that defaults to the undefined value. Study the logic with that in mind.

And, no, this is not a trick question. I haven’t studied the code, just throwing this out there…

The determineWinner functions expects to be passed strings such as 'rock', 'paper', 'scissors' as arguments. Your code is passing strings such as 'computer chose rock.' etc. as arguments to determineWinner. Since none of the if conditions evaluate to true, so determineWinner just returns undefined.

Here are a few issues to correct:

  • In the getUserChoice function,
// You wrote:
return 'You chose ' + userInput;

// It should be:
return userInput;

// OR 
console.log('You chose ' + userInput);
return userInput;
  • In the getComputerChoice function,
// You wrote:
case 0:
    return 'computer chose rock.';
case 1:
    return 'computer chose paper.';
case 2:
    return 'computer chose scissors.';

// It should be:
case 0:
    console.log('computer chose rock.');
    return "rock";
case 1:
    console.log('computer chose paper.');
    return "paper";
case 2:
    console.log('computer chose scissors.');
    return "scissors";

// You could omit the console statements if you prefer. 
// It depends on how you want your program to behave.
2 Likes

Hi,

Why produces error?

Thank you very much for your support :pray:

function whoWins (userChoice,computerChoice){ userChoice === computerChoice ? return 'tie'; userChoice === 'paper' && computerChoice === 'scissors' ? return 'computer win'; userChoice === 'paper' && computerChoice === 'rock' ? return 'user win'; userChoice === 'rock' && computerChoice === 'paper' ? return 'computer win'; userChoice === 'rock' && computerChoice === 'scissors' ? return 'user win'; userChoice === 'scissors' && computerChoice === 'paper' ? return 'user win'; userChoice === 'scissors' && computerChoice === 'rock' ? return 'computer win'; } console.log(whoWins('paper','paper'));

When using the ternary operator, there are 3 operands. The first operand is the expression whose value is used as the condition followed by ? and then two expressions separated by : to deal with the true and false evaluations of the condition. The ternary operator (see documentation) expects expressions not statements after the condition (Statements Vs. Expressions). return is a statement not an expression.
Suppose:

(3 > 2) ? "Greater" : "Not Greater"
// (3 > 2) is an expression. The two strings are also expressions.

return (3 > 2) ? "Greater" : "Not Greater";
// return keyword is not part of the operand (3 > 2)
// It can be thought of as:
// return ((3 > 2) ? "Greater" : "Not Greater");
// After evaluation, simplifies to
// return "Greater";
// which is valid syntax of the form --> return expression;

(3 > 2) ? return "Greater" : return "Not Greater";
// ERROR
// The operands are supposed to be expressions.
// The operands after the ? are statements not expressions. Error will be thrown.

Also, your intent is to chain ternary expressions. You have semi-colons instead of colons, which isn’t correct syntax.
The following will work,

function whoWins (userChoice,computerChoice){
  return userChoice === computerChoice ? 'tie':
  userChoice === 'paper' && computerChoice === 'scissors' ? 'computer win':
  userChoice === 'paper' && computerChoice === 'rock' ? 'user win':
  userChoice === 'rock' && computerChoice === 'paper' ? 'computer win':
  userChoice === 'rock' && computerChoice === 'scissors' ? 'user win':
  userChoice === 'scissors' && computerChoice === 'paper' ? 'user win':
  userChoice === 'scissors' && computerChoice === 'rock' ? 'computer win': 
  "Invalid choices";
}
console.log(whoWins('paper','paper'));
2 Likes

Ooh, of course. I thought I was being clever but the problem is obvious once you point it out. Thanks @mtrtmk !

1 Like

Code keeps giving me the first else statement and wont run through all if statements first. I am lost :melting_face:

///console.log('hi');
const getUserChoice = userInput =>{
userInput = userInput.toLowerCase()

if (userInput === 'rock' || userInput === 'paper' || userInput === 'scissors') {
  return userInput
} else {
   console.log('ERROR, check user input')
   }
};
const getComputerChoice =() =>{
const randomNumber = Math.floor(Math.random() * 3);
switch (randomNumber){
  case 0:
  return 'rock';
  break;
  case 1: 
  return 'paper';
  break;
  case 2: 
  return 'scissors';
  break;
}
};

const determineWinner = (userChoice, computerChoice) => {
if (userChoice ===  computerChoice){
  return 'The game is a tie!';
}
if (userChoice === 'rock' ) {
  if (computerChoice === 'paper')
  return ' Computer won ';
} else {
  return ' You won';
}
if (userChoice === 'paper') {
  if (computerChoice === 'scissors'){
    return 'Computer won';
  } else {
    return ' User Won';
  }
}
if (userChoice === 'scissors') {
  if (computerChoice === 'rock'){
    return ' Computer Won';
  } else {
    return 'User Won';
  }
};
} 

console.log(determineWinner('paper','scissors'));
console.log(determineWinner('paper','paper'));
console.log(determineWinner('paper','rock'));

In JavaScript, if there is only one statement in the body of an if statement, then curly braces are optional (If there are multiple statements in the body, then curly braces are necessary). However, even for single statements, it is generally good practice to use curly braces to avoid ambiguities/mistakes.

// Single statement in body (curly braces optional)

// Without curly braces
if (3 > 2) 
    console.log("The condition is true!");
else 
    console.log("The condition is false");

// With curly braces
if (3 > 2) { 
    console.log("The condition is true!");
} else { 
    console.log("The condition is false");
}

Generally, using curly braces even for single statements is better as it reduces the chances of mistakes especially when writing nested if statements.

// You wrote:
if (userChoice === 'rock' ) {
  if (computerChoice === 'paper')
  return ' Computer won ';
} else {
  return ' You won';
}

// It is equivalent to and is being interpreted as:
if (userChoice === 'rock' ) {
  if (computerChoice === 'paper') {
      return ' Computer won ';
  }
} else {
  return ' You won';
}

The else is being paired with the outer if statement which is not what you want.

Instead,

// It should be:
if (userChoice === 'rock' ) {
    if (computerChoice === 'paper') {
        return ' Computer won ';
    } else {
        return ' You won';
    }
}

Note, how the else is being paired with the nested if.

Thank you so much for clearing that up! I was so confused, and you made it so simple :sweat_smile: I appreciate the help!!

Hi, i’m having a problem with is one

const getUserChoice = (userInput) => {
  userInput = userInput.toLowerCase();
  if (
    userInput === "rock" ||
    userInput === "paper" ||
    userInput === "scissors"
  ) {
    return userInput;
  } else {
    console.log("This is not a good answer");
  }
};

function getComputerChoice() {
  var randomNumber = Math.floor(Math.random() * 3);
  switch (randomNumber) {
    case 0:
      return "rock";
      break;
    case 1:
      return "scissors";
      break;
    case 2:
      return "paper";
      break;
  }
}

function determineWinner(userChoice, computerChoice) {
  if (userChoice === computerChoice) {
    return "The game is a tie";
  }
  /* determine le mztch nul*/

  if (userChoice === "rock") {
    if (computerChoice === "paper") {
      return "computer won!";
    } else {
      return "user won!";
    }
  }

  if (userChoice === "paper") {
    if (computerChoice === "scissors") {
      return "computer won!";
    } else {
      return "user won!";
    }
  }

  if (userChoice === "scissors") {
    if (getComputerChoice === "rock") {
      return "computer won!";
    } else {
      return "user won!";
    }
  }
}

/*console.log(determineWinner("s", "scissors"));*/

const playGame(){
  let userChoice = getUserChoice('rock');
  let computerChoice = getComputerChoice();
  console.log(userChoice +','+ computerChoice);
  console.log(determineWinner(userChoice, computerChoice));
}

playGame();

Can you help me please ?

Two issues to consider.

  • First Issue
// You wrote:
if (userChoice === "scissors") {
    if (getComputerChoice === "rock") {
...

// It should be:
if (userChoice === "scissors") {
    if (computerChoice === "rock") {
...
  • Second Issue
// You wrote:
const playGame(){
...

// Either change it to:
function playGame() {
...

// OR 

// change it to:
const playGame = () => {
...