// Description: This file contains a function checkForWinner() which finds
// the winners of a tic tac toe for any size grid ie 3x3, 4x4, 9x9...
// The recusive function checkLine checks if all elements in a line
// are the same item and if true, pushes that value of the item
// into an array winners. It has a recursive call that calls itself again
// and changes the initial value by adding a jump which is the
// value from one initial starting index to the next line of the same axis
// array of 1D is stays as a 1D array with a 2D theoretical representation
// [0, 1, 2, 3, 4, 5, 6, 7, 8] -->
// ------------------------------> 0 1 2
// ------------------------------> 3 4 5
// ------------------------------> 6 7 8
const checkForWinner = (board = store.game.cells) => {
// checks for tic tac toe of any size square grid
const winners = []
// output array of that will contain the value X or O depending on the winner
const boardSize = Math.sqrt(board.length) | 0
// representation of the length of a side of the square made from the 1D array
const line = { boardStart: 0, boardIncrement: 1, diagonal: boardSize - 1, boardSize: boardSize}
// object that contains relevant board information
const checkLine = function (initialValue, difference, jump = 0, cycle = 1) {
const check = []
// array that will hold the values to be checked if they are the same
cycle = cycle - 1
// de-increment cycle by one each time checkLine is called
for (let i = 0; i < boardSize; i++) { check.push(board[initialValue + difference * i]) }
// push values of board at indexes * difference onto check array
if (check.every(value => value === check[0])) { winners.push(check[0]) }
// if every value in line is the same, push that value onto winners array
if (initialValue === difference) { return checkLine(initialValue - difference, difference + 2) }
// if initialValue and difference are the same (its a diagonal), check the other diagonal
if (!cycle) { return }
// exit recursion when cycle = 0
return checkLine(initialValue + jump, difference, jump, cycle)
// recursively go through other lines until cycle = 0
// increase the initialValue by the jump to switch from one line to the next
}
const checkLines = board => {
checkLine(line.boardStart, line.boardIncrement, line.boardSize, line.boardSize)
// checks all horizontal line
checkLine(line.boardStart, line.boardSize, line.boardIncrement, line.boardSize)
// checks all vertical line
checkLine(line.diagonal, line.diagonal)
// checks both diagonal line
}
checkLines(board)
// invoke checkLines function
winner = winners.filter(winner => winner)[0]
// filter out empty strings
return winner
}