diff --git a/pages/apprenticeship/projects/tictactoe.js b/pages/apprenticeship/projects/tictactoe.js index 9c4a62b..68b9632 100644 --- a/pages/apprenticeship/projects/tictactoe.js +++ b/pages/apprenticeship/projects/tictactoe.js @@ -49,10 +49,19 @@ class TicTacToe extends React.Component { currentPlayerIndex: 0, isFinished: false, winner: null, + winningCells: null, status: 'In Progress', }; } + cellWidth() { + return this.state.boardWidth / this.state.cols; + } + + cellHeight() { + return this.state.boardHeight / this.state.rows; + } + setPlayers(numPlayers) { this.setState({ numPlayers }); } @@ -107,7 +116,7 @@ class TicTacToe extends React.Component { updateGameState() { const board = this.state.board; - const winner = this.findWinner(); + const { winner, winningCells } = this.findWinner(); let hasAvailableMove = false; for (let i = 0; i < this.state.rows && !hasAvailableMove; ++i) { for (let j = 0; j < this.state.cols && !hasAvailableMove; ++j) { @@ -122,9 +131,10 @@ class TicTacToe extends React.Component { if (winner) { // check for win condition this.setState({ - status: 'Winner', + status: `${winner} is the winner!`, isFinished: true, winner: winner, + winningCells: winningCells, }); } else if (!hasAvailableMove) { // check for finished - if no more available moves, then is a draw @@ -148,6 +158,7 @@ class TicTacToe extends React.Component { const board = this.state.board; let winner = null; + let winningCells = null; for (let i = 0; i < rows && !winner; ++i) { for (let j = 0; j < cols && !winner; ++j) { @@ -161,10 +172,11 @@ class TicTacToe extends React.Component { if (j + (winCondition - 1) < cols) { const candidateH = _.range(winCondition).map((k) => { const pos = this.makePos(i, j + k); - return board[pos]; + return pos; }); winner = this.checkCandidateCellsForWinner(candidateH); if (winner) { + winningCells = candidateH; break; } } @@ -173,10 +185,11 @@ class TicTacToe extends React.Component { // down (vertical) const candidateV = _.range(winCondition).map((k) => { const pos = this.makePos(i + k, j); - return board[pos]; + return pos; }); winner = this.checkCandidateCellsForWinner(candidateV); if (winner) { + winningCells = candidateV; break; } @@ -184,10 +197,11 @@ class TicTacToe extends React.Component { if (j - (winCondition - 1) >= 0) { const candidateLD = _.range(winCondition).map((k) => { const pos = this.makePos(i + k, j - k); - return board[pos]; + return pos; }); winner = this.checkCandidateCellsForWinner(candidateLD); if (winner) { + winningCells = candidateLD; break; } } @@ -196,10 +210,11 @@ class TicTacToe extends React.Component { if (j + (winCondition - 1) < cols) { const candidateRD = _.range(winCondition).map((k) => { const pos = this.makePos(i + k, j + k); - return board[pos]; + return pos; }); winner = this.checkCandidateCellsForWinner(candidateRD); if (winner) { + winningCells = candidateRD; break; } } @@ -207,10 +222,17 @@ class TicTacToe extends React.Component { } } - return winner; + return { + winner, + winningCells, + }; } - checkCandidateCellsForWinner(pieces) { + checkCandidateCellsForWinner(positions) { + const board = this.state.board; + const pieces = positions.map((pos) => { + return board[pos]; + }); // returns winner if all pieces in `pieces` list are the same const set = new Set(pieces); const winner = @@ -218,12 +240,18 @@ class TicTacToe extends React.Component { return winner; } + hasWinningCell(pos) { + return this.state.winningCells && this.state.winningCells.includes(pos); + } + reset() { this.setState({ board: {}, currentPlayerIndex: 0, isFinished: false, status: 'In Progress', + winner: null, + winningCells: null, }); } @@ -249,7 +277,7 @@ class TicTacToeBoard extends React.Component { return (