Reputation: 129
I want to prompt the user for an input and if it isn't a valid option reprompt until a valid input is entered.
Right now it always reprompts not matter the input, correct or not.
Here is the code:
var userChoice = prompt("Do you choose rock, paper, scissors or rope?");
while (userChoice != "rock" || "paper" || "scissors" || "rope") {
userChoice = prompt("Sorry invalid input, please enter either: rock, paper,scissors, or rope.");
}
Seems like it should be a simple thing to do, am I misunderstanding how to use while loops? maybe the operators are wrong? haven't been able to find anything useful, any help is appreciated!
Upvotes: 2
Views: 24248
Reputation: 604
I'll try a more generic answer:
The while
loop runs while whatever in the brackets is TRUE
.
The way ||
works, it will evaluate to TRUE
if at least one of the operands is TRUE
.
So in your case even if you select
userChoice = "rock";
userChoice != "rock" => FALSE
whatever comes after ||
will still evaluate to TRUE
because
"rock" != "paper" => TRUE
and thus your whole condition in the brackets will evaluate to TRUE
.
So in order to break out of the loop, you need to have the condition in the brackets evaluate to FALSE
.
The way &&
works, it will evaluate to FALSE
if at least one of the operands evaluates to FALSE
.
And since
userChoice = "rock";
userChoice != "rock" => FALSE
the loop does not even check the rest of the conditions you might have and breaks out of the loop.
Upvotes: 0
Reputation: 22322
for more complicated rules (such as ignoring case sensitivity), it is possible to use regular expressions, e.g. match:
while( ! userChoice.match(/^\s*(?:rock|paper|scissors|rope)\s*$/i)) { ... }
(see explanation of the regex on https://regex101.com/r/sV3tJ1/1#javascript)
note: thanks Willem Van Onsem for suggesting regex
also avaliable are object literals:
var validChoices = {rock: true,
paper: true,
scissors: true,
rope: true},
userChoice = ...
while ( ! validChoices.hasOwnProperty(userChoice)) {
...
}
or ES6 Set for the newest browsers as of 2016: new Set(["rock", "paper", ...])
Upvotes: 2
Reputation: 3265
You could also use an array and indexOf
var userChoice = prompt("rock, paper, scissors, rope?").toLowerCase();
while (["rock", "paper", "scissors", "rope"].indexOf(userChoice) === -1) {
userChoice = prompt("Please choose: rock, paper, scissors, rope?").toLowerCase();
}
alert("You chose '" + userChoice + "'");
Upvotes: 5
Reputation: 386654
Maybe an array is smarter to use with Array.prototype.indexOf()
.
var userChoice;
while (!~["rock", "paper", "scissors", "rope"].indexOf(userChoice)) {
userChoice = prompt("Sorry invalid input, please enter either: rock, paper,scissors, or rope.");
}
Upvotes: 2
Reputation: 476719
The syntax "rock" || "paper"
is valid, but the OR will bind later than the equality check, so basically you write:
while ((userChoice != "rock") || "paper" || "scissors" || "rope") {
//...
}
Now since you use such or's, you basically do an effectiveness check and at least "paper"
is effective. You can however get the behavior you aim, by using explicit checks and using the &&
operator instead of the ||
:
while (userChoice !== "rock" && userChoice !== "paper" && userChoice !== "scissors" && userChoice !== "rope") {
//...
}
Upvotes: 4
Reputation: 70523
While userChoice does not equal any of the choices... so AND
while (userChoice != "rock" && userChoice != "paper" && userChoice != "scissors" && userChoice != "rope") {
Upvotes: 2