I am making a tic-tac-toe with HTML, CSS and JavaScript. To the result verification, I am using two arrays, one counting the "X" moves, and the other couting the "O" moves with its id numbers. And an IF
block, using array.includes()
with all cases that are wins. But always this code return that "x won".
I tried this code
function result_check() {
if (moves_counter_x.includes(
1 && 4 && 7 || 2 && 5 && 8 ||
3 && 6 && 9 || 1 && 2 && 3 ||
4 && 5 && 6 || 7 && 8 && 9)) {
console.log("x won")
}
}
I tried this code too:
function result_check() {
if (moves_counter_x.includes(1 && 4 && 7) ||
moves_counter_x.includes(2 && 5 && 8) ||
moves_counter_x.includes(3 && 6 && 9) ||
moves_counter_x.includes(1 && 2 && 3) ||
moves_counter_x.includes(4 && 5 && 6) ||
moves_counter_x.includes(7 && 8 && 9)) {
console.log("x won")
}
}
But always this code return that x won. By example, when the the numbers on moves_counter_x are [1, 5, 6].
Why this function isn’t working?
4
Answers
You can’t put the logical operators inside the
includes()
argument, it doesn’t automatically distribute. You have to call the function multiple times, and combine the results.The "and" operator does not combine its operands. Instead it returns the first operand if it is falsy, and the second operand otherwise.
Thus we have
When you write
It is identical to
What you actually want to write is
&&
and||
are fully evaluated before being passed to a function, somoves_counter_x.includes(1 && 4 && 7)
evaluates to the last term in the sequence to be evaluated (7
, always, because1
and4
are both truthy, so7
is the result of the expression), and you’re only checking ifmoves_counter_x.includes(7)
. You have to check the "includiness" for each value independently, and&&
and||
the return fromincludes
together, e.g. for a simplified subset of your test, instead of:you’d need to change it to:
There are ways to simplify this with other data structures and utilities (e.g.
some
andevery
methods combined with looping), but for a beginner, learn the basics of using the boolean operators correctly first.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every
Use
Array::every()
to check whether each array item is contained in another array:Replace
num1 && num2 && num3
to[num1,num2,num3].every(num => arr.includes(num))
.You can make your own
include()
function to check whether an array contains a set of values to have a similar syntax of what you tried. Note that&&
logical operator provides the first truthy value if available or the first value if not. So you don’t check existence of your operands since you check existence of the&&
expression’s result. You should pass them as separate arguments.To go fancy you could put your moves into 1 array: