skip to Main Content

I have made a simple Rock Paper Scissors game that can be played in the console. It uses a series of if/else if statements to compare the inputs by the user against the computers selections and outputs a winner based on this. My issue is that the code is a bit long and repetitive so I’m not sure if there is a way to possibly make it more compact.

This is my code at the moment:

function start(computerSelection, playerSelection){

  if (computerSelection === playerSelection){
    return "It's a tie!"
  }
  else if (computerSelection === "rock" && playerSelection === "paper"){
    playerScore += 1;
    return "You win!";
  }
  else if (computerSelection === "rock" && playerSelection === "scissors"){
    computerScore += 1;
    return "Computer wins!"; 
  }
  else if (computerSelection === "paper" && playerSelection === "rock"){
    computerScore += 1;
    return "Computer wins!"; 
  }
  else if (computerSelection === "paper" && playerSelection === "scissors"){
    playerScore += 1;
    return "You win!";
  }
  else if (computerSelection === "scissors" && playerSelection === "paper"){
    computerScore += 1;
    return "Computer wins!"; 
  }
  else if (computerSelection === "scissors" && playerSelection === "rock"){
    playerScore += 1;
    return "You win!";
    
  }
  else{
    return "Invalid entry!"
  }

}

This is not all the code for the game, just the section that I’m looking to shorten.

9

Answers


  1. you can use a data driven system:

    
    const winner = { scissors: 'rock', rock: 'paper', paper: 'scissors' }
      
    function start(computerSelection, playerSelection)
      {
      if (computerSelection === playerSelection)  return "It's a tie!";
      if (playerSelection === winner[computerSelection]) { playerScore++;   return "You win!"; }
      if (computerSelection === winner[playerSelection]) { computerScore++; return "Computer wins!"; }
      return "Invalid entry!";
      }
    
    Login or Signup to reply.
  2. Firstly you don’t need to do this kind of if/else logic when returning in each block:

    if (x) {
      return 'foo';
    } else if (y) {
      return 'bar';
    else {
      return 'lorem ipsum';
    }
    

    That can be written as just

    if (x) {
      return 'foo';
    } 
    
    if (y) {
      return 'bar';
    }
    
    return 'lorem ipsum';
    

    Secondly, if you want to use a switch statement, as you’re not just checking a single value, you could try:

    switch (true) {
        case computerSelection === playerSelection:
            return "It's a tie!";
        case computerSelection === "rock" && playerSelection === "paper":
            return "You win!";
        case computerSelection === "rock" && playerSelection === "scissors": 
            return "Computer wins!"; 
        ... etc
        
        default:
            return "Invalid entry!"
    }
    

    Thirdly, in your function you increment playerScore and computerScore, but they’re not initialised anywhere, and you don’t use them anywhere. So I removed them from my answer.

    Login or Signup to reply.
  3. Very quickly, without switch/case and without making too many changes to your original code:

    function start(computerSelection, playerSelection){
      if (computerSelection === playerSelection){
        return "It's a tie!"
      }
      if (computerSelection === "rock" && playerSelection === "paper") ||
         (computerSelection === "paper" && playerSelection === "scissors") ||
         (computerSelection === "scissors" && playerSelection === "rock"){
        playerScore += 1;
        return "You win!";
      }
      if (computerSelection === "rock" && playerSelection === "scissors") ||
         (computerSelection === "paper" && playerSelection === "rock") || 
         (computerSelection === "scissors" && playerSelection === "paper"){
        computerScore += 1;
        return "Computer wins!"; 
      }
      return "Invalid entry!"
    }
    

    In my opinion, you don’t need any else statement here and you can summarize conditions with the same outcome.

    Login or Signup to reply.
  4. This is shorter

    let computerScore = 0;
    let playerScore = 0;
    const win = {"rock"    : "scissors", 
                 "paper"   : "rock", 
                 "scissors": "paper"};
    const start = (computerSelection, playerSelection) => {
      if(computerSelection === playerSelection) return "It's a tie!";
      if(win[computerSelection] === playerSelection) return ++computerScore, "Computer wins!";
      if(win[playerSelection] === computerSelection) return ++playerScore, "You win!";
      return "Invalid entry!";
    };
    
    /// tests
    console.log("rock","scissors",start("rock","scissors"))
    console.log("paper","scissors",start("paper","scissors"))
    console.log("rock","rock",start("rock","rock"))
    console.log("scissors","paper",start("scissors","paper"))
    console.log("paper","rock",start("paper","rock"))
    
    console.log(computerScore,playerScore)
    Login or Signup to reply.
  5. You can use switch case to write those statments,it will look like this:

    function start(computerSelection, playerSelection) {
      let result = "";
      switch (true) {
        case computerSelection === playerSelection:
          result = "It's a tie!";
          break;
        case computerSelection === "rock":
          result = playerSelection === "paper" ? "You win!" : "Computer wins!";
          break;
        case computerSelection === "paper":
          result = playerSelection === "scissors" ? "You win!" : "Computer wins!";
          break;
        case computerSelection === "scissors":
          result = playerSelection === "rock" ? "You win!" : "Computer wins!";
          break;
        default:
          result = "Invalid entry!";
      }
      if (result === "You win!") {
        playerScore += 1;
      } else if (result === "Computer wins!") {
        computerScore += 1;
      }
      return result;
    }
    
    Login or Signup to reply.
  6. Something like this?

    function start(computerSelection, playerSelection) {
      // Possible outcomes
      const outcomes = {
        rock: { scissors: 'Computer wins!', paper: 'You win!', rock: "It's a tie!" },
        paper: { rock: 'Computer wins!', scissors: 'You win!', paper: "It's a tie!" },
        scissors: { paper: 'Computer wins!', rock: 'You win!', scissors: "It's a tie!" }
      };
      // Tie?
      if (computerSelection === playerSelection) {
        return "It's a tie!";
      }
    
      // Who won?
      if (outcomes[computerSelection][playerSelection] === 'You win!') {
        playerScore += 1; // Increment the player's score
      } else {
        computerScore += 1; // Increment the computer's score
      }
    
      // Return the outcome of the round
      return outcomes[computerSelection][playerSelection];
    }
    

    You can also add this:

    // Are the selections valid choices?
      if (!(computerSelection in outcomes) || !(playerSelection in outcomes)) {
        return 'Invalid entry!';
      }
    
    Login or Signup to reply.
  7. A simplified version of the above code.

    function start(computerSelection, playerSelection) {
      let playerScore, computerScore;
      const outcomes = {
        rock: { scissors: 'Computer wins!', paper: 'You win!' },
        paper: { rock: 'Computer wins!', scissors: 'You win!' },
        scissors: { paper: 'Computer wins!', rock: 'You win!' }
      };
      if (!(computerSelection in outcomes) || !(playerSelection in outcomes)) {
        return 'Invalid entry!';
      }
      if (computerSelection === playerSelection) {
        return "It's a tie!";
      }
      const outcome = outcomes[computerSelection][playerSelection];
      if (outcome) {
        if (outcome === 'Computer wins!') {
          computerScore += 1;
        } else {
          playerScore += 1;
        }
        return outcome;
      }
    }
    console.log(start("scissors","rock"))
    Login or Signup to reply.
  8. You actually only need to determine who wins. Here is one idea to do that.

    See also …

    const choices = [`rock`, `paper`, `scissors`];
    
    for (let i=0; i < 10; i+=1) {
      const me = choices[Math.floor(Math.random() * choices.length)];
      const pc = choices[Math.floor(Math.random() * choices.length)];
      console.log(determineWin(me, pc));
    }
    
    function determineWin(youSelection, pcSelection){
      const wins = [`rock-paper`, `paper-scissors`, `scissors-rock`];
      const youWin = wins.find(v => v ===`${youSelection}-${pcSelection}`);
      const tie = youSelection === pcSelection;
      return `you: ${youSelection} - pc: ${pcSelection} => ${
        tie ? `TIE` : youWin ? `You win` : `Computer wins`}`;
    }
    Login or Signup to reply.
  9. you can make like this:

    function start(computerSelection, playerSelection) {
      const winConditions = {
        rock: "scissors",
        paper: "rock",
        scissors: "paper"
      };
    
      if (computerSelection === playerSelection) {
        return "It's a tie!";
      } else if (winConditions[computerSelection] === playerSelection) {
        playerScore += 1;
        return "You win!";
      } else if (winConditions[playerSelection] === computerSelection) {
        computerScore += 1;
        return "Computer wins!";
      } else {
        return "Invalid entry!";
      }
    }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search