Created
December 23, 2018 18:08
-
-
Save abohannon/54e03083efebfcd8b476383087da1fa4 to your computer and use it in GitHub Desktop.
TicTacToe game of any size that determines a winner in O(1)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class TicTacToe { | |
constructor(size) { | |
this.size = size | |
this.center = Math.floor(this.size / 2) | |
this.state = { | |
board: [], | |
score: [], | |
move: 0, | |
} | |
} | |
initGame() { | |
const board = [] | |
for (let i = 0; i < this.size; i++) { | |
board.push(Array(this.size).fill(0)) | |
} | |
this.state.board = board | |
this.state.score = Array(2 + (2 * this.size)).fill(0) | |
} | |
onMove(row, column, player) { | |
const { board } = this.state | |
if (board[row][column] !== 0) return console.log('Move already taken. Please choose another.') | |
this.updateBoard(row, column, player) | |
this.updateScore(row, column, player) | |
this.printBoard() | |
} | |
updateBoard(row, column, player) { | |
const { board } = this.state | |
switch (player) { | |
case 1: | |
board[row][column] = 1 | |
this.state.move = this.state.move + 1 | |
break | |
case -1: | |
board[row][column] = -1 | |
this.state.move = this.state.move + 1 | |
break | |
default: | |
return null | |
} | |
} | |
updateScore(row, column, player) { | |
const { score } = this.state | |
const leftDiagonalIndex = this.size * 2 | |
const rightDiagonalIndex = this.size * 2 + 1 | |
if (row === this.center && column === this.center) { | |
score[leftDiagonalIndex] += player | |
this.checkScore(leftDiagonalIndex, player) | |
score[rightDiagonalIndex] += player | |
this.checkScore(rightDiagonalIndex, player) | |
} else { | |
if (row === column) { | |
score[leftDiagonalIndex] += player | |
this.checkScore(leftDiagonalIndex, player) | |
} | |
if (row + column === this.size - 1) { | |
score[rightDiagonalIndex] += player | |
this.checkScore(rightDiagonalIndex, player) | |
} | |
} | |
score[row] += player | |
this.checkScore(row, player) | |
score[column + this.size] += player | |
this.checkScore(column + this.size, player) | |
if (this.move === Math.pow(this.size, 2)) return this.printStalemate() | |
this.printScore() | |
} | |
checkScore(index, player) { | |
const { score } = this.state | |
if (score[index] === this.size || score[index] === -Math.abs(this.size)) { | |
return this.printWinner(player) | |
} | |
} | |
printBoard() { | |
console.log(this.state.board) | |
} | |
printScore() { | |
console.log(this.state.score) | |
} | |
printWinner(player) { | |
console.log(`*!*@*# ${player} IS THE WINNER #*@*!*`) | |
} | |
printStalemate() { | |
console.log('STALEMATE') | |
} | |
} | |
const game = new TicTacToe(4) | |
game.initGame() | |
game.onMove(0,0,1) | |
game.onMove(1,1,-1) | |
game.onMove(1,0,1) | |
game.onMove(0,2,-1) | |
game.onMove(2,2,1) | |
game.onMove(2,1,-1) | |
game.onMove(1,2,1) | |
game.onMove(2,0,-1) | |
game.onMove(3,3,1) | |
game.onMove(0,1,-1) | |
game.onMove(2,3,1) | |
game.onMove(3,1,-1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment