Squirrel
Squirrel

Reputation: 51

Rock, Paper, Scissors, Lizard, Spock in JavaScript

I'm kind of new to JavaScript. I just started learning it, and I decided to make a 'Rock, Paper, Scissors, Lizard, Spock' game. Here is the code:

var userChoice = prompt("Do you choose rock, paper, scissors, lizard, or spock?")
var computerChoice = Math.random();
if (computerChoice < 0.2) {
    computerChoice = "rock";
} else if (computerChoice <= 0.4) {
    computerChoice = "paper";
} else if (computerChoice <= 0.6) {
    computerChoice = "scissors";
} else if (computerChoice <= 0.8) {
    computerChoice = "lizard";
} else {
    computerChoice = "spock";
}

alert("The computer chose " + computerChoice);

var compare = function(choice1, choice2){
    if (choice1 === choice2) {
        alert("And... It's a tie!");
    }

//If the user chose rock...
else if (choice1 === "rock") {
    if (choice2 === "scissors") {
        alert("Rock wins!");
    } else if (choice2 === "paper") {
        alert("Paper wins!");
    } else if (choice2 === "lizard") {
        alert("Rock wins!");
    } else {
        alert("Spock wins!");
    }
}

//If the user chose paper...
else if (choice1 === "paper") {
    if (choice2 === "scissors") {
        alert("Scissors wins!");
    } else if (choice2 === "rock") {
        alert("Paper wins!");
    } else if (choice2 === "lizard") {
        alert("Lizard wins!");
    } else {
        alert("Paper wins!");
    }
}

//If the user chose scissors...
else if (choice1 === "scissors") {
    if (choice2 === "paper") {
        alert("Scissors wins!");
    } else if (choice2 === "rock") {
        alert("Rock wins!");
    } else if (choice2 === "lizard") {
        alert("Scissors wins!");
    } else {
        alert("Spock wins!");
    }
}

//If the user chose lizard...
else if (choice1 === "lizard") {
    if (choice2 === "scissors") {
        alert("Scissors wins!");
    } else if (choice2 === "rock") {
        alert("Rock wins!");
    } else if (choice2 === "paper") {
        alert("Lizard wins!");
    } else {
        alert("Lizard wins!");
    }
}

//If the user chose spock...
else if (choice1 === "spock") {
    if (choice2 === "scissors") {
        alert("Spock wins!");
    } else if (choice2 === "rock") {
        alert("Spock wins!");
    } else if (choice2 === "lizard") {
        alert("Lizard wins!");
    } else {
        alert("Paper wins!");
    }
}
};
compare(userChoice, computerChoice);

There are 2 main things that I want to add to my code but I don't know how to:

  1. Right now, if the user inputs, for example, 'Rock' with a capital 'R', it doesn't get recognized as one of the five valid inputs (rock, paper, scissors, lizard, and spock). Is there a way to make it so that if the user inputs something valid with a capital letter (or letters) it will still be valid?

  2. I want to add something so that whenever someone puts in something invalid (e.g. "sloth") it will alert them that their input is invalid and will ask them, again, to put in rock, paper, scissors, lizard, or spock.

Upvotes: 5

Views: 7890

Answers (6)

HLNGR
HLNGR

Reputation: 1

If you help yourself with a table of combinations like this one -
https://commons.wikimedia.org/wiki/File:Normal_form_matrix_of_Rock-paper-scissors-lizard-Spock.jpg

I use 2 instead of -1 (0 - Tie; 1 - row win; 2 - row looses)

Then your code becomes:

    var options=["Rock","Paper","Scissors","Lizard","Spock"]
    var outcomes=[[0,2,1,1,2],[1,0,2,2,1],[2,1,0,1,2],[2,1,2,0,1],[1,2,1,2,0]]

    function RPSLS(user){

    var computer=Math.floor(Math.random()*5);

    if (outcomes[user][computer]==0){alert("Tie");}
    if (outcomes[user][computer]==1){alert("User Wins");}
    if (outcomes[user][computer]==2){alert("Computer Wins");}
    txt1.value=options[user];
    txt2.value=options[computer];}

Then the HMTL part of the output:

    Please choose:<br>
    <button onclick="RPSLS(0)">Rock</button>
    <button onclick="RPSLS(1)">Paper</button>
    <button onclick="RPSLS(2)">Scissors</button>
    <button onclick="RPSLS(3)">Lizard</button>
    <button onclick="RPSLS(4)">Spock</button>
    <button onclick="RPSLS(Math.floor(Math.random()*4))">Random    Game</button><P>
    <textarea id="txt1"></textarea><textarea id="txt1"></textarea>

Upvotes: 0

Mke Spa Guy
Mke Spa Guy

Reputation: 793

Simplify result function with math. http://jsfiddle.net/afrievalt/qBbJn/

var options = ["paper", "rock", "lizard", "spock", "scissors"],
  result = [" ties ", " beats ", " loses to "],
  bigBang = function(choice1, choice2) {
      var index1 = options.indexOf(choice1), //spock => 3
          index2 = options.indexOf(choice2), //rock=> 1
          dif = index2 - index1; // 1 - 3 => -2
      if(dif < 0) { // -2 < 0 => truthy
          dif += options.length; // -2 + 5 => 3
      }
      while(dif > 2) { //3 > 2 => truthy
          dif -= 2; // 3 - 2 => 1
      }
      return choice1 + result[dif] + choice2; //spock beats rock
  };

.

  bigBang("spock", "paper");  // spock losses to paper 

  var i = Math.floor(Math.random() * 5),
      randomChoice = options[i];
  bigBang(randomChoice, userChoice);

this function will also work with options = ["cockroach", "nuke", "shoe"], (from that 70s show) or any odd length array like options = ["water", "fire", "paper", "rock", "tree", "metal", "mud"] //todo: throw error if any index = -1

Upvotes: 5

Jon P
Jon P

Reputation: 19792

Lets go object oriented on this. It will reduce repitition in the logic:

//Set up the choices with what they can beat
//This is a hash table of objects you can referecne by name
var choices  =  {rock : {name: "Rock", defeats: ["scissors","lizard"]},
                 paper: {name: "Paper", defeats: ["rock", "spock"]},
                 scissors: {name: "Scissors", defeats: ["paper", "lizard"]},
                 lizard: {name: "Lizard", defeats:["paper","spock"]},
                 spock: {name: "Spock", defeats:["scissors","rock"]}
                };


//Get the computers choice
var computerChoice = Math.random();
if (computerChoice < 0.2) {
    computerChoice = "rock";
} else if (computerChoice <= 0.4) {
    computerChoice = "paper";
} else if (computerChoice <= 0.6) {
    computerChoice = "scissors";
} else if (computerChoice <= 0.8) {
    computerChoice = "lizard";
} else {
    computerChoice = "spock";
}


//Get the users choice, normalising to lower case    
var userChoice = prompt("Do you choose rock, paper, scissors, lizard, or spock?").toLowerCase();

alert("The computer chose " + computerChoice);    

//Check for a tie
if(computerChoice == userChoice){
    alert("It's a tie");
//Check for a valid choice
}else if(choices[userChoice] === undefined){
    alert("Invalid Choice");
}else{
    //Get the chosen one as an object
    userChoice = choices[userChoice];



    //Check For a win
    /*var victory = false;
    for(var i = 0; i < userChoice.defeats.length; i++){
        if(computerChoice == userChoice.defeats[i])
        {
            victory = true;
            break;
        }
    }*/

    //Improved check, inspired by Mke Spa Guy
    var victory = userChoice.defeats.indexOf(computerChoice) > -1;

    //Display result
    if(victory) {
        alert("Vitory! " + userChoice.name + " wins!")
    }else{
        alert("Defeat, " + computerChoice + " wins!");
    }   
}

Thats it, and Spocks' your uncle.

Demo

Demo with full action : e.g: Paper Covers Rock;

More Reading:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects

http://www.mojavelinux.com/articles/javascript_hashes.html

Upvotes: 4

Matthew Pigram
Matthew Pigram

Reputation: 1430

I would do something like the following (please note that the syntax may be off slightly):

var compare = function (choice1, choice2)
{
    switch (choice1.tolower())
    {
        case "rock"
            RockPicked(choice2);
            break;
        case "scissors"
            ScissorsPicked(choice2);
            break;
        ....
        ....
        case default
            alert ("Selection was invalid")
            break;
    }

}

// if the user picked rock then we compare the computers choice and decide winner
var RockPicked = function(choice2)
{
    if (choice2 === "scissors") 
    {
        alert("Rock wins!");
    } 
    else if (choice2 === "paper") 
    {
        alert("Paper wins!");
    } 
    else if (choice2 === "lizard") 
    {
        alert("Rock wins!");
    } 
    else 
    {
        alert("Spock wins!");
    }
}

Upvotes: 0

I wrestled a bear once.
I wrestled a bear once.

Reputation: 23379

I would write a function to get the correct response instead of doing it all inline.. that's just me..

function getUserChoice(){
    var invalidPin = true;
    var response;
    while(invalidPin){
        response = prompt("choose your thing..");
            if(response == "rock" || response == "paper" || response == "scizerz"){
                invalidPin = false;
            }
        }
    }
    return response;
}

then you can get the user's choice simply by calling the function

var userChoice = getUserChoice();

Upvotes: 1

Jason Baker
Jason Baker

Reputation: 2483

As several users have mentioned, your best bet for comparing is to convert the input to lowercase.

For your second point, I would wrap the input parsing in a loop, like this:

while(true){
    var input = getInput();

    if(isValid(input)){
        // check for the winner
        break;
    }else{
        // tell the user that their input is invalid
    }
}

Upvotes: 0

Related Questions