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")
            }
        })
G-8
  • 107
  • 1
  • 7
  • Does this answer your question? [Check whether an array exists in an array of arrays?](https://stackoverflow.com/questions/19543514/check-whether-an-array-exists-in-an-array-of-arrays) – Nathan Chu Nov 17 '20 at 19:28
  • 1
    Arrays can't be compared to arrays using `===`, so the first method won't work. – Yousername Nov 17 '20 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']);` – Nathan Chu Nov 17 '20 at 19:37
  • @nthnchu thanks for your suggestion but I was looking for a native method to do this. – G-8 Nov 17 '20 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. – Nathan Chu Nov 17 '20 at 19:48
  • @nthnchu true, I meant using arrays native methods which imo is a simpler approach than creating a function like the accepted answer in that question. – G-8 Nov 17 '20 at 20:09

3 Answers3

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.

Khant
  • 958
  • 5
  • 20
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()

Tushar Kale
  • 159
  • 1
  • 12
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");
}
Kulvar
  • 1,139
  • 9
  • 22
  • 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. – G-8 Nov 17 '20 at 20:11
  • 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. – Kulvar Nov 17 '20 at 20:13
  • [link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) I don't understand what do they mean by return here – G-8 Nov 17 '20 at 20:24
  • 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; }` – Kulvar Nov 17 '20 at 20:59