please have a look on my if condition. I am just refreshing my javascript and I am wondering, how I could check, if the inserted variables, are the ones I want to be used.
Your code is being evaluated like this:
if (
choice1 // Non-empty strings always evaluate to TRUE
&&
choice2 === "rock"
// The above are evaluated together
// If both are not TRUE, FALSE is the result
||
"paper" // Non-empty string. TRUE
||
"scissors" // Non-empty string. TRUE
)
This pseudo code might help:
if (value of AND block
||
true
||
true)
Since OR has a true
available every time, the if block will run every time.
When you say:
if(someString) { /* do something */ }
what this means in english is "if the value of someString is not the empty string, do something." In Javascript this is commonly referred to as "truthiness," so the truthiness of any string is true, except the empty string.
When you say:
if(someCondition || someString) { /* do something */ }
written in English this means "if someCondition evaluates to true, or if someString is truthy, then do something." Since "paper" is always truthy, anything || "paper"
is always true.
For your purposes, I would re-write the code like this:
var validValues = ["rock", "paper", "scissors"];
if(validValues.indexOf(choice1) >= 0 && validValues.indexOf(choice2) >= 0) {
/* do something */
}
Basically, make a list of valid values, then check if both choices appear in that list. The game of rock, paper, scissors will never get more valid values, but in other similar situations this list may grow or shrink over time.
The issue is your condition will always evaluate to true since the || "paper"
condition is going to return a truth-y value. That alone makes the entire condition true, since the values are OR'd, so it always passes. You're checking for choice1 && choice2 === "rock"
, which isn't really written correctly. As for || scissors
that will be false since scissors
is undefined here.
Consider taking this approach instead:
var validOptions = ["rock", "paper", "scissors"];
if(validOptions.indexOf(choice1) > -1 && validOptions.indexOf(choice2) > -1) {
// now compare choice1 and choice2 to determine the winner
} else {
alert("Something went wrong");
}
Note that the solution shown doesn't trim the user input or account of case sensitivity. To address that you could use a regex with the ignore-case flag:
var re = /\b(?:rock|paper|scissors)\b/i;
if (re.test(choice1) && re.test(choice2)) {
// ...
}
function compare(choice1, choice2){
var identical = choice1 === choice2;
var options = ["rock", "paper", "scissors"];
if (identical && (options.indexOf(choice1) > -1))
alert("Pass");
else
alert("Not alike");
}
In this code, identical
will be either true or false, and if it is true, you can check if it matches any of the values inside the options array.
I believe it shoud look like:
if ((choice1=="rock" || choice1=="paper" || choice1=="scissors") &&
(choice2=="rock" || choice2=="paper" || choice2=="scissors")){...
There are lots of indexOf answers with arrays, but you can also use an object for valid resopnses:
var validResponses = {rock:'', paper:'', scissors:''};
if (choice1 in validResponses && choice2 in validResponses) {
// all good
}
of if you want be safe:
if (validResponses.hasOwnProperty(choice1) && validResponses.hasOwnProperty(choice2)) {
...
}