also w.r.t. the winning checks, make sure you have independantly tested that function thoroughly (did you learn how to do that in fCC?) Because you don’t want to waste time debugging something that has nothing to do with react.
i think you should put the highlight in a useEffect.
Reason is, it is triggering a side-effect in the UI that should be cleaned up on reset.
Interesting I’ll look into this.
I’ll have to look more deeply into it but it seems to work fine in PvP without the computer player. I can play as many games as I want, hitting reset each time, and it works perfectly if I play X and O myself.
Only when I check the box and introduce the computer player is when it seems to get buggy.
I got it
This line was mutating my winningPatterns
array which holds all of the possible winning combinations:
//remove previous move
pattern.splice(pattern.indexOf(point.toString()), 1);
I did not expect that pattern
and winningPatterns
would refer to the same array in memory. for (let pattern of winningPatterns) {
const computerMove = (point, newGrid) => {
//check the winning patterns that contain recent move
for (let pattern of winningPatterns) {
if (pattern.includes(point.toString())) {
//remove previous move
pattern.splice(pattern.indexOf(point.toString()), 1);
//choose a free space from the pattern
for (let array of pattern) {
let [zz,xx,yy] = array.split(",")
if (newGrid[zz][xx][yy] == "") {
console.log(winningPatterns)
return [zz,xx,yy];
}
}
}
}
}
So every time the computer moved it would modify the winningPatterns
array and you would need less complete lines to win each time.
Which is why someone would win with only one spot taken sometimes.
That line was a bit superfluous anyways I just had to comment it out. It was one of those optimizations that saved 1 cycle.
I always say: test your functions before using them.
It’s the best way to avoid major headaches running after shadows and ghosts.
For react, vitest is a good tool to setup some test cases to thoroughly verify each function. Especially those ‘pure’ ones that are supposed to behave exactly the same way each time.
Good for you for figuring out the issue. (and good find on understanding that the for loop didn’t actually clone anything in memory.)
Thanks, I’ll check out vitest!