Rock Paper Scissors project - how to ensure wrong input will stop the program

Hi!
I’m back from a break now relearning js
got a a problem i cant sort out

At the Rock Paper Scissors project at the functions unit under the full stack engineer course

Rock Paper Scissors Lesson

I’m mostly finished, before doing the 14th step though I wanna make sure if a user
inputs invalid option the game will only pop the error message

currently determine winner function continues although userChoice returns error msg

How do I make the program stop after delivering the error msg
without resorting to another else if statement in determineWinner();
to make it happen?

my code below:

//recieve user choice

const getUserChoice = (userInput) => {

  userInput = userInput.toLowerCase();

  if( userInput === 'rock' || userInput === 'paper' || userInput === 'scissors'){

    return userInput;

  }else{

   console.log('Invalid selection,choose only rock paper scissors');

  }

}

/*test function user

console.log(getUserChoice('paper')); */

//calculate computer choice

const getComputerChoice = () =>{

  let computerChoice = Math.floor(Math.random()*3);

  switch (computerChoice){

    case 0:

    return computerChoice='rock';

    break;

    case 1:

    return computerChoice='paper';

    break;

    case 2:

    return computerChoice='scissors';

    break;

  }

}

/* test function computer

console.log(getComputerChoice());  */

const determineWinner = (userChoice,computerChoice) =>{

  if (userChoice === computerChoice) {  

   return 'The game is tied';

  }else if ( userChoice === 'rock') {

    if( computerChoice === 'paper'){

      return 'The computer wins!';

    }else{

      return 'Player wins!';

    }

  }else if( userChoice ==='paper'){

      if( computerChoice ==='rock'){

        return 'Player wins!';

      }else{

        return 'The computer wins!';

      }

   }else{

      if( computerChoice ==='rock'){

        return 'The computer wins';

      }else{

        return 'Player wins!';

      }

  } 

}

/*testing the function

determineWinner(getUserChoice('scissors'),getComputerChoice()); */



//starts up the game

const playGame = () => {

  const userChoice=getUserChoice('NUMNUM');

  const computerChoice=getComputerChoice();

console.log(`Player choose ${userChoice}.

Computer choose ${computerChoice}`);

 console.log(determineWinner(userChoice,computerChoice));

};

playGame();

Thanks!

Hi @ace7884
you could remove the else statement from the getUserChoice function and pass the user input directly to the initially calling function playGame. Then you could already check if the input is valid in the function playGame.

Code snippet
if(userChoice){
    console.log(`Player choose ${userChoice}.
  	Computer choose ${computerChoice}`);
   	console.log(determineWinner(userChoice,computerChoice));
  }else{
  	console.log('Invalid selection,choose only rock paper scissors');
  }
1 Like

As a note, in your switch cases you don’t need ‘break’ after ‘return’ because return will stop anymore logic running in the function anyway, so it cannot fall through to the next case.

I could also move the else statement from getUserChoice()

use it as new else if block at determineWinner()

but i rather see if its possible to achieve the outcome given the lesson instructions given

Isnt break or default required syntex for switch statements?

Yes, you could do that, but that wouldn’t help your cause. Once you’d entered the function determineWinner(), the code you want to prevent from running already ran.

The lesson doesn’t require you to assign the user’s choice within the function body of playGame() as that wouldn’t be best practice anyway. If you imagine the game being a part of a website, the user’s choice would be done via an html input field and passed to the calling function.

Neither are actually required.

switch(pattern) {
    case a:
        console.log(a);
        //fall through to b
    case b:
        console.log(b);
        // fall through to c
    case c:
        console.log(c);
        break;
        // Will not fall through to d
    case d:
        console.log(d);
        return d;
        // return will not run anymore code in the function so won't fall through
    case e:
        console.log(e);
        break;
// If pattern equals a:
// a will be logged
// b will be logged
// c will be logged

//if pattern equals b
// b will be logged
// c will be logged

//if pattern equals c, d or e
// only the matched value will be logged.

The above is a perfectly valid switch statement.

What will happen though is because there is no return or break at the end of one case it will go into the case below it and run the code in that one too - this is called falling through.
This is why break is typically used, to break out of the switch statement and run the code after it. Sometimes return is used, it too will stop falling through because no more code will get run.

The most common case for fall through is when you have multiple cases doing the same thing, i.e.

switch(num) {
    case 1:
    // fall through to 2
    case 2:
    // fall through to 3
    case 3:
        console.log("under 4");
        break;
    case 4:
    // fall through to 5
    case 5:
    // fall through to 6
    case 6:
        console.log("under 7"
        break;
     // Etc, etc
}

Generally fall through is considered bad apart from when you have multiple cases sharing one code block like above.

default just allows you to explicitly say what to do if not case matches. But you will typically have one to log/throw an error to make it visible something unexpected.

1 Like

True but im guessing as at this phase of learning they want users to work with what they learned so far,so input etc would be taught later.
knowing that not considering real life practicallity rather the context of the assignment itself
how could that check be made?

and thnks guys for your inputs

Yes, that’s right. But they wouldn’t teach you bad practices. The solution I suggested is in line with what was taught so far and makes things easier rather than more complicated. And it would lead to the result you are trying to achieve: That the game isn’t played unless the input is valid.
So removing the else statement from the getUserChoice function and inserting it in the playGame function does the trick.

playGame function code
const playGame = (input) => {
	let userChoice = getUserChoice(input);
  if(userChoice){
    console.log(`Player choose ${userChoice}.
  	Computer choose ${computerChoice}`);
   	console.log(determineWinner(userChoice,computerChoice));
  }else{
  	console.log('Invalid selection,choose only rock paper scissors');
  }
};

playGame('NUMNUM');

:thinking: :thinking: :thinking:
haha i confused input with html input forms

i see
so i can assign a boolean to userchoice whereas if it isnt an allowed input that boolean becomes false
then check it like u did at the start of playgame()

thanks!

No, you understood it correctly, I just mentioned that as an example why you would avoid assigning a string to the function call of getUserChoice as in your previous version.

It is not a bool. If you log it to the console like this:

const playGame = (input) => {
	let userChoice = getUserChoice(input);
	console.log(userChoice);

and call playGame('scissors'); it would log ‘scissors’.
If you call playGame('vljv') it logs ‘undefined’ and goes straight to the else statement.
You could also write it like that:

if(userChoice !== undefined)

PS. I forgot to add let computerChoice = getComputerChoice(); in my code snippet for playGame().