Christopher Clear
Christopher Clear

Reputation: 91

Update function parameter withing function

I have been learning JS on my own for a while using codecademy.com and one task was to make a JS rock, paper, scissors game. At the end it asked for some enhancements, like if it was a tie how would you make it to where you could choose again and if the user had an invalid entry how would you address that problem.

The following is the entire JS game, fairly small. I just need some help on how to get the first if statement in my function to work properly by correctly checking the first parameter and if it is invalid have a prompt that updates the parameter without affecting the second. and then rerun the function. My "OR" operators don't seem to be working either.

Also I would like to know if there is a cleaner/better way to write my second if statement. It works fine I'm just curious if there is a better way.

Thank you all for your help!

var userChoice = prompt("Do you choose rock, paper or scissors?");
var computerChoice = Math.random();
if (computerChoice < 0.34) {
    computerChoice = "rock";
} else if(computerChoice <= 0.67) {
    computerChoice = "paper";
} else {
    computerChoice = "scissors";
} console.log("Computer: " + computerChoice);

var compare = function (choice1, choice2){

    if (choice1 !== "rock" || "scissors" || "paper"){
       choice1 = prompt("Invalid entry, please reenter")}

     if (choice1 === choice2){ 
         var userChoice = prompt("Tie! Choose Again!");
         var computerChoice = Math.random();
         if (computerChoice < 0.34) {
                computerChoice = "rock";
            } else if(computerChoice <= 0.67) {
                computerChoice = "paper";
            } else {
                computerChoice = "scissors";
            } console.log("Computer: " + computerChoice);
     compare(userChoice, computerChoice);


    } else if (choice1 === "rock"){

        if(choice2 === "scissors"){
        return "rock wins";
        }else{
            return "Paper wins"};
    } else if (choice1 === "paper"){
        if (choice2 === "rock"){
            return "paper wins";
        }else { 
            return "scissors win"}
    } else if (choice1 === "scissors"){
        if (choice2 === "rock"){
            return "rock wins"
        }else {
            return "scissors wins"}
    };
};
compare(userChoice, computerChoice);

Upvotes: 0

Views: 47

Answers (3)

Me.Name
Me.Name

Reputation: 12544

Since the 2nd prompt would have to check again, it's advisable to merge the checks in a loop or external function. e.g.:

var options = ['rock', 'paper', 'scissors'];

function getUserInput(){
    var txt= "Do you choose rock, paper or scissors?";
    while(true){ //loop until valid input or cancelled
        var res = prompt(txt);
        if(res==null)return null; //user cancelled
        var ind = options.indexOf(res.toLowerCase()); //alter input (in this case only tolowercase, but you could add trimming and such)
        if(ind >=0) return options[ind]; //if valid, return the stored value to be able to have the same value for comparison. You could choose to work with the indices too
        txt = "Invalid entry, please reenter";
    }
}

This also performs a toLowerCase on the input, so input as 'Rock' or 'ROCK' would be valid too.

To further avoid syntax discrepancies, you could reuse the options array for the computer input with something like

var computerChoice = options[ Math.floor(Math.random() * 3)];

This will use the strings in the options arrays. Math.floor(Math.random() * 3) will generate an integer of 0,1 or 2 with the same chance as the < 0.34 etc. comparisons.


Edit: Couldn't resist adding an example of why using the indices themselves would be useful. It would enable the code to compare to the next element (using modulo to revert to the first element) to determine the winner if the options are ordered correctly.

var options = ['rock', 'scissors', 'paper']; //ordered such that each value beats the next value (where the last value beats the first)

function getUserInput(txt){
    while(true){ //loop until valid input or cancelled
        var res = prompt(txt || "Do you choose rock, paper or scissors?"); //prompt with a pre defined text or the default text ( || makes sure undefined is replaced with the right hand value)
        if(res==null)return null; //user cancelled
        var ind = options.indexOf(res.toLowerCase()); //alter input (in this case only tolowercase, but you could add trimming and such)
        if(ind >=0) return ind; //if valid, return the index
        txt = "Invalid entry, please reenter";
    }
}


function runGame(promptText){
    var userChoice = getUserInput(promptText);
    if(userChoice===null)return; //user cancelled
    var computerChoice = Math.floor(Math.random() * 3); //generates a random number of 0,1 or 2 
    console.log("Computer: " + options[computerChoice]);

    if(userChoice === computerChoice)
        return runGame("Tie! Choose Again!"); //in case of Tie, start over with the prompText of Tie

    if(userChoice === (computerChoice + 1) % 3)   //the next value: +1 the % 3 (modulo 3) returns the remainder if the '+1' value is divided by 3 and thus turns 3 into 0   
        return options[computerChoice] + ' beats ' + options[userChoice]  + ' (Computer wins)';        
    return options[userChoice] + ' beats ' + options[computerChoice]  + ' (User wins)';        

}

var res = runGame();
if(res)
   alert(res);

Fiddle

Upvotes: 1

Curtis
Curtis

Reputation: 103368

You have incorrect logic for what you are trying to do.

You need to change the first line of the if statement to:

if (choice1 !== "rock" || choice1 !== "scissors" || choice1 !== "paper"){

Alternatively:

var options = ["rock", "scissors", "paper"];
if (options.indexOf(choice1)==-1){

Upvotes: 1

Michael Kunst
Michael Kunst

Reputation: 2988

I made a little fiddle for you. Take a look at this code:

var validChoices = ['rock', 'paper', 'scissors'];
if (validChoices.indexOf(choice1) == -1){
   hoice1 = prompt("Invalid entry, please reenter")
   compare(choice1, choice2);
}

At first you say which choices are valid. If the user has given none of them, you ask him again to make a choice and call your function again with the new, user chosen choice1.

About you're if condition: what you have done is the following, either:

  • choice1 is rock

  • "scissors" is true

  • "paper" is true

As javascript is weakly typed, a string is true. To compare it correctly with the way you wanted take a look at Curts answer.

Upvotes: 1

Related Questions