In this game though I think that rather than using a fixed array to find winning combinations it would be better to calculate the position of the selected cell, then look for the three adjacent cells in the available directions for matching cells dynamically.
These functions do that with basic arithmetics. You'll need to invoke checkWinner()
with the position of the clicked cell (its index
in the squares
array) and the player that is performing the play (so invoke the function before changing currentPlayer
, or store it for later use).
function checkCandidates(index, cssName, callbackId) {
// Look for the three adjacent cells, as defined by callbackId().
for (let i = 1; i <= 3; i++) {
let id = callbackId(index, i);
if (!squares[id].classList.contains(cssName)) {
return false;
}
}
return true;
}
function checkWinner(index, player) {
const cssName = (player == 2) ? 'player-two' : 'player-one';
const cellPos = (index + 1);
const cellRow = Math.ceil(cellPos / 7);
const cellCol = Math.ceil(cellPos - ((cellRow - 1) * 7));
// Check bottom cells (after, in the same column).
if (cellRow < 4 && checkCandidates(index, cssName, (index, i) => index + (7 * i))) {
return true;
}
// Check left cells (before, in the same row).
if (cellCol >= 4 && checkCandidates(index, cssName, (index, i) => index - i)) {
return true;
}
// Check top cells (before, in the same column).
if (cellRow >= 4 && checkCandidates(index, cssName, (index, i) => index - (7 * i))) {
return true;
}
// Check right cells (after, in the same column).
if (cellCol <= 4 && checkCandidates(index, cssName, (index, i) => index + i)) {
return true;
}
// No winner yet!
return false;
}