Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rock, Paper, Scissors, Lizard, Spock in JavaScript

Tags:

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.

like image 513
Squirrel Avatar asked Mar 25 '14 00:03

Squirrel


2 Answers

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

like image 184
Mke Spa Guy Avatar answered Oct 13 '22 08:10

Mke Spa Guy


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

like image 26
Jon P Avatar answered Oct 13 '22 08:10

Jon P