Skip to content

Instantly share code, notes, and snippets.

@ktilcu
Last active March 26, 2019 13:49
Show Gist options
  • Save ktilcu/89a93289a810262ba3898ff591b44a30 to your computer and use it in GitHub Desktop.
Save ktilcu/89a93289a810262ba3898ff591b44a30 to your computer and use it in GitHub Desktop.
Implement a connect 4 win detector
const board = [[t, f, t, f], [f, f, f, f], [f, f, f, f], [f, t, f, f]];
/*
0 1 2 3 4 5 6 7 8
0 O O O O O O O O B B = Winning col
1 X O O O A O O O B
2 O X O O O A O O B
3 O O X O O O A O B
4 O O O X O O O A O X and A = Winning DownRight Diagonals
5 O O O O O O O O A
6 O O O O O O O E O
7 O Y Y Y Y O E O O Y = Winning row
8 O O O O O E O O O
9 O O O O E O O O O E = Winning DownLeft Diagonal
*/
const determineDiagonalAnchor = (x, y) =>
// dr: y = x+b
// dr: b = y - x
// dr: x = y - b
// dl: y = -x+b
// dl: b = y + x
// dl: x = b - y
({
dr: [y - (y - x), y - x],
dl: [y + x - x, y + x],
});
const aggregateBoard = board =>
Object.values(
board.reduce(
(acc, row, y) =>
row.reduce((acc2, slot, x) => {
const {dr: drAnchor, dl: dlAnchor} = determineDiagonalAnchor(x, y);
const winSets = [
`column${x}`,
`row${y}`,
`drDiag${drAnchor}`,
`dlDiag${dlAnchor}`,
];
winSets.forEach(set => {
if (!acc2[set] || !Array.isArray(acc2[set])) {
acc2[set] = [];
}
acc2[set].push(slot);
});
return acc2;
}, acc),
{},
),
);
// [ [true, false, true, false] ]
const hasContiguousElements = num => result =>
result.reduce((cont, slot) => {
if (cont.length >= num) return cont;
if (slot === false) return [];
return [...cont, slot];
}, []).length >= num;
const isWinner = aggregateBoard(board).some(hasContiguousElements(4));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment