简体   繁体   中英

Use of logical and comparison operators in conditions (javascript)

I want the user to input his answer in a rock-paper-scissors game in the following line of code.

userChoice = prompt("Do you choose rock, paper or scissors?");

However, in case the user writes something other than exactly "rock", "paper" or "scissors", he is supposed to choose again, which I tried to do with this piece of code:

while (userChoice !== "rock" || "paper" || "scissors") {
    userChoice = prompt("Invalid choice. Please change your answer.");
};

The problem I have is that the program keeps recognizing the given input as invalid, even if it is "rock", "paper" or "scissors".


While typing this, I managed to find a solution on my own.

while (userChoice !== "rock" && userChoice !== "paper" && userChoice !== "scissors") {
    userChoice = prompt("Invalid choice. Please change your answer.");
};

That way does make sense and the first condition probably didn't work because even if you type a correct answer (eg "paper"), it still doesn't equal the other two answers (in this case "rock" and "scissors"), which is why the program kept saying the answer has been invalid, right? Or is it a syntax error? Now (with the working condition), the choice of the user has to be neither "rock" nor "paper" nor "scissors" and thus it works properly.

Also, is there possibly an easier and shorter way of writing that condition?

Note: I hope it's fine that parts of the solution are already included as they could help other coders.

Use indexOf

while (["rock", "paper", "scissors"].indexOf(userChoice) > -1) {

Your first attempt

while (userChoice !== "rock" || "paper" || "scissors") {

is technically an infinite loop because

|| "paper" 

for example, technically evaluates to true or a truthy value

Two examples

One with an array and Array.prototype.indexOf() :

 var userChoice; while (!~['rock', 'paper', 'scissors'].indexOf(userChoice)) { userChoice = prompt("Invalid choice. Please change your answer."); }; 

And another with an object and the in operator:

The in operator returns true if the specified property is in the specified object.

 var userChoice; while (!(userChoice in {rock: 1, paper: 1, scissors: 1})) { userChoice = prompt("Invalid choice. Please change your answer."); }; 

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Rock Papper Scissors Game</title>
    </head>
    <body>
        <h1>Play Rock Papper Scissors?</h1>
        <button id="start">Play?</button>
        <script> 
            function rpsGame() {
                var computerChoice = Math.random(),
                    userChoice = prompt('Do you choose rock, paper, or scissors');
                function getComputerChoice() {
                    if (computerChoice <= 0.33) {
                        computerChoice = 'rock';
                    } else if (computerChoice <= 0.66 && computerChoice >= 0.33) {
                        computerChoice = 'paper';
                    } else {
                        computerChoice = 'scissors';
                    }
                }
                function playAgain() {
                    var restart = prompt('Would you like to play again, yes or no?').toLowerCase();
                    switch(restart) {
                    case 'yes':
                        rpsGame();
                        break;
                    default:
                        alert('Okay, see you later!');
                    }
                }
                function compare() {
                    var choice1 = userChoice.toLowerCase(),
                        choice2 = computerChoice,
                        tie = "The computer chose " + choice2 + ", and you chose " + choice1 + ". The result is a tie!",
                        win = "The computer chose " + choice2 + ", and you chose " + choice1 + ". You win!",
                        lose = "The computer chose " + choice2 + ", and you chose " + choice1 + ". The computer wins!";

                    switch (choice1) {
                    case "":
                        alert("You didn't enter anything. Maybe we can play later!");
                        break;
                    case 'rock':
                        if (choice2 === 'scissors') {
                            alert(win);
                        } else if (choice2 === 'rock') {
                            alert(tie);
                        } else {
                            alert(lose);
                        }
                        playAgain();
                        break;
                    case 'paper':
                        if (choice2 === 'rock') {
                            alert(win);
                        } else if (choice2 === 'paper') {
                            alert(tie);
                        } else {
                            alert(lose);
                        }
                        playAgain();
                        break;
                    case 'scissors':
                        if (choice2 === 'paper') {
                            alert(win);
                        } else if (choice2 === 'scissors') {
                            alert(tie);
                        } else {
                            alert(lose);
                        }
                        playAgain();
                        break;
                    default:
                        alert(choice1.substring(0,1).toUpperCase() + choice1.substring(1, choice1.length).toLowerCase() + " is an invalid choice. Please change your answer.");
                        rpsGame();
                    }
                }
                getComputerChoice();
                compare();
            }
            document.getElementById('start').addEventListener('click', rpsGame);
        </script>
    </body>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM