0

I'm trying to make a tictactoe game using javascript. I have the winning conditions in a nested array

const winConditions = [
            [0, 1, 2],
            [3, 4, 5],
            [6, 7, 8],
            [0, 3, 6],
            [1, 4, 7],
            [2, 5, 8],
            [0, 4, 8],
            [2, 4, 6]
]

and I have my current player's marked boxes indices in an array

let squaresIndices = [0,4,8]

I'm trying to stop the game when any of the winning conditions occur. I have tried each of the following and I can't figure out why they don't work.

winConditions.forEach((array) => {
    if (array === squaresIndices){
        alert("Game Over")
    }
//////

if (winConditions.includes(squaresIndices)){
    alert ("Game Over")
}
//////
        winConditions.some((arr) =>{
            if (arr.every((square) => {
                squaresIndices.includes(square)
            })) {
                alert("Game Over")
            }
        })
6
  • Does this answer your question? Check whether an array exists in an array of arrays? Commented Nov 17, 2020 at 19:28
  • 1
    Arrays can't be compared to arrays using ===, so the first method won't work. Commented Nov 17, 2020 at 19:28
  • Arrays are compared by references. The following prints true: var a = ['a', 'b', 'c']; console.log(a === a);, however the following prints false: console.log(['a', 'b', 'c'] === ['a', 'b', 'c']); Commented Nov 17, 2020 at 19:37
  • @nthnchu thanks for your suggestion but I was looking for a native method to do this. Commented Nov 17, 2020 at 19:41
  • @G-8 I don't really understand what you mean by "native." Most of the answers given in the other question use vanilla js, if that's what you mean. Commented Nov 17, 2020 at 19:48

3 Answers 3

1

First of all Array cannot be compared

Try this example

let a = [0,2,3]
let b = [0,2,3]

alert( a === b )

What you need to understand is that when you save an array. What you actually doing is created a reference to that array in memory.

Then again try this example

let a = [0,2,3]
let b = a

alert( a === b )

You will get true, Why? Because in first case you are trying to two separate addresses in memory. Meaning that a & b got different addresses but same kind of apartment. But in second case you are comparing the same address.

So the easiest way you can do is convert them into string then try to compare them.

JSON.stringify(a)==JSON.stringify(b)

Then you will get your desire result. While this could work if the order of the properties will always the same for those array instances, this leaves the door open for extremely nasty bugs that could be hard to track down.

Sign up to request clarification or add additional context in comments.

Comments

0

Your last example is correct if not for forgetting to return the value and moving the if outside.

const winConditions = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6]
];

const squaresIndices = [0, 4, 8];

const isWin = winConditions.some(
    (arr) =>
    {
        // return if this combination is matching or not
        return arr.every(
            (square) =>
            {
                // return if the value matches or not
                return squaresIndices.includes(square);
            }
        );
    }
);

// Then test the result
if (isWin)
{
    alert("Game Over");
}

4 Comments

can you explain please why I have to use return since .some() and .every() return booleans. This works for me but I can't understand why I can't use it in a conditional.
They don't return boolean, it's your job to return a boolean to tell when it's good or not. If you don't return anything, it's considered erroneous in every situation.
link I don't understand what do they mean by return here
The function you pass as an argument is the testing function. It's used by the function to know whether or not the item checked is valid or not. The function you make has to return either true (valid) or false (reject). There is an implicit way to return a value in arrow functions. (item) => item.checked without curly braces is equivalent to (item) => { return item.checked; }
0
winConditions.forEach((array) => {
    if(JSON.stringify(array)==JSON.stringify(squaresIndices)){
        alert("Game Over")
    }
})

You cannot compare two arrays directly in javascript. You need to convert it to string for comparison. You can also use toString() instead of JSON.stringify()

3 Comments

This works and is good but you should provide some explanation
@nthnchu Edited my answer
This works but I prefer Kulvar's answer since it follows the logic I'm trying to follow. Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.