diff --git a/src/common/CommonMancalaGame.ts b/src/common/CommonMancalaGame.ts index ea612fb..0c0e850 100644 --- a/src/common/CommonMancalaGame.ts +++ b/src/common/CommonMancalaGame.ts @@ -6,10 +6,18 @@ import { GRLastStoneInEmptyPit } from './game_rules/GRLastStoneInEmptyPit'; export class CommonMancalaGame extends MancalaGame { constructor(id: string, player1Id: string, player2Id: string) { - super(id, new CommonBoard(), player1Id, player2Id, player1Id, [ - new GRLastStoneInEmptyPit(), - new GRLastStoneInBank(), - new GRClearBoardAtEnd() - ]); + super( + id, + new CommonBoard(), + player1Id, + player2Id, + player1Id, + [ + new GRLastStoneInEmptyPit(), + new GRLastStoneInBank(), + new GRClearBoardAtEnd() + ], + [] + ); } } diff --git a/src/core/HistoryItem.ts b/src/core/HistoryItem.ts new file mode 100644 index 0000000..107b3ec --- /dev/null +++ b/src/core/HistoryItem.ts @@ -0,0 +1,16 @@ +export class HistoryItem { + boardSnapshot: number[]; + constructor(boardSnapshot: number[]) { + this.boardSnapshot = boardSnapshot; + } +} + +export class MoveHistoryItem extends HistoryItem { + playerId: string; + moveIndex: number; + constructor(playerId: string, moveIndex: number, boardSnapshot: number[]) { + super(boardSnapshot); + this.playerId = playerId; + this.moveIndex = moveIndex; + } +} diff --git a/src/core/MancalaGame.ts b/src/core/MancalaGame.ts index b73647b..afa6038 100644 --- a/src/core/MancalaGame.ts +++ b/src/core/MancalaGame.ts @@ -1,5 +1,6 @@ import { Board, PitType } from './Board'; import { GameRule } from './GameRule'; +import { HistoryItem, MoveHistoryItem } from './HistoryItem'; export type GameState = 'initial' | 'playing' | 'ended'; @@ -11,6 +12,7 @@ export class MancalaGame { turnPlayerId: string; state: GameState; gameRules: GameRule[]; + history: HistoryItem[]; constructor( id: string, @@ -19,6 +21,7 @@ export class MancalaGame { player2Id: string, turnPlayerId: string, gameRules: GameRule[], + history: HistoryItem[], state: GameState = 'initial' ) { this.id = id; @@ -28,6 +31,7 @@ export class MancalaGame { this.turnPlayerId = turnPlayerId; this.state = state; this.gameRules = gameRules; + this.history = history; this.listenBoardMoveEvents(); } @@ -126,7 +130,11 @@ export class MancalaGame { this.state = 'playing'; } if (this.canPlayerMove(playerId, pitIndex)) { - this.board.move(this.getBoardIndexByPlayerId(playerId, pitIndex)); + const moveIndex = this.getBoardIndexByPlayerId(playerId, pitIndex); + this.board.move(moveIndex); + this.history.push( + new MoveHistoryItem(playerId, moveIndex, this.board.getStoneArray()) + ); if (this.checkGameIsEnded()) { this.state = 'ended'; } @@ -206,6 +214,7 @@ export class MancalaGame { mancalaGame.player2Id, mancalaGame.turnPlayerId, mancalaGame.gameRules, + mancalaGame.history, mancalaGame.state ); } diff --git a/tests/MancalaGame.test.ts b/tests/MancalaGame.test.ts index 22c6894..475c019 100644 --- a/tests/MancalaGame.test.ts +++ b/tests/MancalaGame.test.ts @@ -2,17 +2,26 @@ import { GRClearBoardAtEnd } from '../src/common/game_rules/GRClearBoardAtEnd'; import { GRLastStoneInBank } from '../src/common/game_rules/GRLastStoneInBank'; import { GRLastStoneInEmptyPit } from '../src/common/game_rules/GRLastStoneInEmptyPit'; import { Board } from '../src/core/Board'; +import { MoveHistoryItem } from '../src/core/HistoryItem'; import { MancalaGame } from '../src/core/MancalaGame'; function createGame(): MancalaGame { const board = new Board(6, 4); const player1Id = '0'; const player2Id = '1'; - const game = new MancalaGame('0', board, player1Id, player2Id, player1Id, [ - new GRLastStoneInEmptyPit(), - new GRLastStoneInBank(), - new GRClearBoardAtEnd() - ]); + const game = new MancalaGame( + '0', + board, + player1Id, + player2Id, + player1Id, + [ + new GRLastStoneInEmptyPit(), + new GRLastStoneInBank(), + new GRClearBoardAtEnd() + ], + [] + ); return game; } @@ -107,4 +116,36 @@ describe('Game Test', () => { 0, 0, 4, 4, 4, 4, 5, 4, 4, 4, 4, 0, 4, 0 ]); }); + + test('test game history', () => { + const game = createGame(); + const player1Id = '0'; + const player2Id = '1'; + game.moveByPlayerPit(player1Id, 0); + game.moveByPlayerPit(player2Id, 0); + game.moveByPlayerPit(player1Id, 1); + game.moveByPlayerPit(player2Id, 1); + expect(game.history).toStrictEqual([ + new MoveHistoryItem( + player1Id, + 0, + [1, 5, 5, 5, 4, 4, 0, 4, 4, 4, 4, 4, 4, 0] + ), + new MoveHistoryItem( + player2Id, + 7, + [1, 5, 5, 5, 4, 4, 0, 1, 5, 5, 5, 4, 4, 0] + ), + new MoveHistoryItem( + player1Id, + 1, + [1, 1, 6, 6, 5, 5, 0, 1, 5, 5, 5, 4, 4, 0] + ), + new MoveHistoryItem( + player2Id, + 8, + [1, 1, 6, 6, 5, 5, 0, 1, 1, 6, 6, 5, 5, 0] + ) + ]); + }); }); diff --git a/tests/game_rules/GRClearBoardAtEnd.test.ts b/tests/game_rules/GRClearBoardAtEnd.test.ts index 30f8109..a54f2fd 100644 --- a/tests/game_rules/GRClearBoardAtEnd.test.ts +++ b/tests/game_rules/GRClearBoardAtEnd.test.ts @@ -8,11 +8,19 @@ function createGame(): MancalaGame { const board = new Board(6, 4); const player1Id = '0'; const player2Id = '1'; - const game = new MancalaGame('0', board, player1Id, player2Id, player1Id, [ - new GRLastStoneInEmptyPit(), - new GRLastStoneInBank(), - new GRClearBoardAtEnd() - ]); + const game = new MancalaGame( + '0', + board, + player1Id, + player2Id, + player1Id, + [ + new GRLastStoneInEmptyPit(), + new GRLastStoneInBank(), + new GRClearBoardAtEnd() + ], + [] + ); return game; }