Write a Rock Paper Scissors game without if/else in JavaScript

In my first JavaScript course, the instructor asked us to write a ‘rock paper scissors’ game between users(us) and computer. I believe a lot of JavaScript learners have written their own version of this game before.

This was my previous solution:

`/* step1: Use build-in function - prompt() to return user's choice and store it in the variable - userChoice. */`
`let userChoice = prompt('please choose one from rock, paper or scissors, and type into the box below');`
`/* step2: in case user's input has different cases, to be more specific, uses .toLowerCase() convert all return values into lower cases. */`
`userChoice = userChoice.toLowerCase();`
`/* step3: building an array, declared as choiceStack to let computer choose from */`
`let choiceStack = ['paper', 'rock', 'scissors'];`
`/* step4: make use of two JS build-in functions - Math.random()(to generate random number between 0-1), multiply it by 3, because we have 3 choices in our choiceStack array; and pass it into Math.floor()(to return the largest integer less than or equal to a given number) */`
`let randomNum = Math.floor(Math.random() * 3);`
`/* step5: pass the generated number as an index to choiceStack, to get the element in the array and store it in another variable - computerChoice */`
`let computerChoice = choiceStack[randomNum];`
`/* step6: log the result on the console */`
`console.log(`Your choice is \${userChoice}, the computer's choice is \${computerChoice}.`);`
`/* final step: Compare each choice with if/else statement, then print the result on the console */`
`if (userChoice === computerChoice){console.log("Tie!");`
`}else if (userChoice === 'paper' && computerChoice === 'rock'){console.log("You win!");`
`}else if (userChoice === 'rock' && computerChoice === 'scissors'){console.log("You win!");`
`}else if (userChoice === 'scissors' && computerChoice === 'rock'){console.log("You lose!");`
`}else if (userChoice === 'rock' && computerChoice === 'paper'){console.log("You lose!");`
`}else if (userChoice === 'paper' && computerChoice === 'scissors'){console.log("You lose!");`
`}else if (userChoice === 'scissors' || computerChoice === 'paper'){console.log("You win!");`
`}else{console.log("Invalid input, please try again");}`

Wow, the code seems a bit long, right? That’s because I have to list all the possible combinations with the if/else statements. The program ended up with tons of ‘if’, ‘else’, ‘userChoice’, ‘computerChoice’,……etc.

So I asked myself this question: Can I make the game without any if/else statement and make the code cleaner and more readable? After I learnt more about arrays, I made a two dimensional chart as follow, and filled all the possible results from user and computer in it.

Then I put this chart into a two dimensional array, stored in another variable — results, which looks like below:

`const results = [['t', 'c', 'u'],['u', 't', 'c'],['c', 'u', 't'],];`

The next step is to convert user’s input into an index, so that we can find the game result in the two dimensional array.

`let userChoiceIndex = choiceStack.indexOf(userChoice);`

Since we already has the computerChoice index(the random number we generated before), let’s map them into the two dimensional array.

`let userResult = results[randomNum][userChoiceIndex];`

Now if you log it into your console, you can see the result could be ‘c’, or ‘u’, or ‘t’. But we still need to get the real result, not just few characters right? So I made an object(right, I just learnt about object today) to convert those characters into sentences.

`const resultMap = {'t': "Tie",'u': "You win",'c': "You lose"};`

At last, use the bracket notation to find the sentence from the result, and log it on the console.

`console.log(resultMap[userResult]);`

The complete example looks like this:

`/* get user's input */`
`let userChoice = prompt('please choose one from rock, paper or scissors, and type into the box below');`
`/* convert user's input into index */`
`userChoice = userChoice.toLowerCase();let choiceStack = ['paper', 'rock', 'scissors'];let userChoiceIndex = choiceStack.indexOf(userChoice);`
`/* generate computer's choice */`
`let randomNum = Math.floor(Math.random() * 3);let computerChoice = choiceStack[randomNum];`
`/* log the each choices on the console */`
`console.log(`Your choice is \${userChoice}, the computer's choice is \${computerChoice}.`);`
`/* make a two dimensional array */`
`const results = [['t', 'c', 'u'],['u', 't', 'c'],['c', 'u', 't'],];`
`/* use userChoice index (because in the end we just need the user result) to find the result in this two dimensional array */`
`let userResult = results[randomNum][userChoiceIndex];`
`/* make an object to convert the final result into a sentence, so we can log it on the console */`
`const resultMap = {'t': "Tie",'u': "You win",'c': "You lose"};`
`console.log(resultMap[userResult]);`

In this way, without tons of if/else, tons of typing, we made a same but smarter ‘rock, paper, scissors’ game. And of course, put all our basic array and object knowledge into practice.

If you have another solution, welcome to share with me. Because ‘rock, paper, scissors’ can solve a lot of ‘life problems’ right?