From 5a4caca9a41c2e17c0aab46a3cd13c8ec5f5101b Mon Sep 17 00:00:00 2001 From: Halit Aksoy Date: Sun, 8 May 2022 16:59:58 +0300 Subject: [PATCH] add GameStep for game rules --- src/common/game_rules/GRClearBoardAtEnd.ts | 39 ++++++++++++++++++- src/common/game_rules/GRLastStoneInBank.ts | 4 ++ .../game_rules/GRLastStoneInEmptyPit.ts | 26 +++++++++++-- tests/game_rules/GRClearBoardAtEnd.test.ts | 7 ++++ .../game_rules/GRLastStoneInEmptyPit.test.ts | 27 +++++++++++++ 5 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 tests/game_rules/GRLastStoneInEmptyPit.test.ts diff --git a/src/common/game_rules/GRClearBoardAtEnd.ts b/src/common/game_rules/GRClearBoardAtEnd.ts index caa2a55..d2e08d5 100644 --- a/src/common/game_rules/GRClearBoardAtEnd.ts +++ b/src/common/game_rules/GRClearBoardAtEnd.ts @@ -1,17 +1,52 @@ +import { Board } from '../../core/Board'; import { GameRule } from '../../core/GameRule'; +import { GameStep } from '../../core/HistoryItem'; import { MancalaGame } from '../../core/MancalaGame'; +export const GAME_STEP_BOARD_CLEARED = 'GAME_STEP_BOARD_CLEARED'; + +export type ClearBoardAtEndData = { pitIndexesThatHasStone: number[] }; + export class GRClearBoardAtEnd implements GameRule { onGameMoveStart(game: MancalaGame, index: number): void {} onGameMove(game: MancalaGame, index: number): void {} onGameMoveEnd(game: MancalaGame, index: number): void { if (game.getPlayer1StoneCountInPits() === 0) { + const clearBoardAtEndData = { + pitIndexesThatHasStone: this.getPitIndexesThatHasStone(game.board) + }; game.board.player1Bank.stoneCount += game.getPlayer2StoneCountInPits(); game.board.clearPlayer2Pits(); - } - if (game.getPlayer2StoneCountInPits() === 0) { + this.addGameStep(game, index, clearBoardAtEndData); + } else if (game.getPlayer2StoneCountInPits() === 0) { + const clearBoardAtEndData = { + pitIndexesThatHasStone: this.getPitIndexesThatHasStone(game.board) + }; game.board.player2Bank.stoneCount += game.getPlayer1StoneCountInPits(); game.board.clearPlayer1Pits(); + this.addGameStep(game, index, clearBoardAtEndData); } } + + private getPitIndexesThatHasStone(board: Board): number[] { + let index = 0; + const indexList = []; + for (const stoneCount of board.getStoneArray()) { + if (stoneCount > 0 && board.checkPitTypeIsNormalPitByIndex(index)) { + indexList.push(index); + } + index++; + } + return indexList; + } + + private addGameStep( + game: MancalaGame, + index: number, + clearBoardAtEndData: ClearBoardAtEndData + ) { + game.addGameStep( + new GameStep(index, GAME_STEP_BOARD_CLEARED, clearBoardAtEndData) + ); + } } diff --git a/src/common/game_rules/GRLastStoneInBank.ts b/src/common/game_rules/GRLastStoneInBank.ts index 3969d02..d64b596 100644 --- a/src/common/game_rules/GRLastStoneInBank.ts +++ b/src/common/game_rules/GRLastStoneInBank.ts @@ -1,6 +1,9 @@ import { GameRule } from '../../core/GameRule'; +import { GameStep } from '../../core/HistoryItem'; import { MancalaGame } from '../../core/MancalaGame'; +export const GAME_STEP_LAST_STONE_IN_BANK = 'GAME_STEP_LAST_STONE_IN_BANK'; + export class GRLastStoneInBank implements GameRule { onGameMoveStart(game: MancalaGame, index: number): void {} onGameMove(game: MancalaGame, index: number): void {} @@ -11,6 +14,7 @@ export class GRLastStoneInBank implements GameRule { (pitType === 'player1Bank' && game.isTurnPlayer1()) || (pitType === 'player2Bank' && game.isTurnPlayer2()) ) { + game.addGameStep(new GameStep(index, GAME_STEP_LAST_STONE_IN_BANK)); } else { game.changePlayerTurn(); } diff --git a/src/common/game_rules/GRLastStoneInEmptyPit.ts b/src/common/game_rules/GRLastStoneInEmptyPit.ts index 7481e4e..4e46c5c 100644 --- a/src/common/game_rules/GRLastStoneInEmptyPit.ts +++ b/src/common/game_rules/GRLastStoneInEmptyPit.ts @@ -1,6 +1,12 @@ import { GameRule } from '../../core/GameRule'; +import { GameStep } from '../../core/HistoryItem'; import { MancalaGame } from '../../core/MancalaGame'; +export const GAME_STEP_LAST_STONE_IN_EMPTY_PIT = + 'GAME_STEP_LAST_STONE_IN_EMPTY_PIT'; + +export type LastStoneInEmptyPitData = { oppositeIndex: number }; + export class GRLastStoneInEmptyPit implements GameRule { onGameMoveStart(game: MancalaGame, index: number): void {} onGameMove(game: MancalaGame, index: number): void {} @@ -10,26 +16,38 @@ export class GRLastStoneInEmptyPit implements GameRule { const pitType = game.board.getPitTypeByIndex(index); if (pit.stoneCount === 1) { if (pitType === 'player1Pit' && game.isTurnPlayer1()) { - const oppositePit = - game.board.pits[game.board.getOppositePitIndex(index)]; + const oppositeIndex = game.board.getOppositePitIndex(index); + const oppositePit = game.board.pits[oppositeIndex]; if (oppositePit.stoneCount > 0) { const player1BankIndex = game.board.pits[game.board.player1BankIndex()]; player1BankIndex.stoneCount += 1 + oppositePit.stoneCount; oppositePit.stoneCount = 0; pit.stoneCount = 0; + this.addGameStep(game, index, { oppositeIndex }); } } else if (pitType === 'player2Pit' && game.isTurnPlayer2()) { - const oppositePit = - game.board.pits[game.board.getOppositePitIndex(index)]; + const oppositeIndex = game.board.getOppositePitIndex(index); + const oppositePit = game.board.pits[oppositeIndex]; if (oppositePit.stoneCount > 0) { const player2BankIndex = game.board.pits[game.board.player2BankIndex()]; player2BankIndex.stoneCount += 1 + oppositePit.stoneCount; oppositePit.stoneCount = 0; pit.stoneCount = 0; + this.addGameStep(game, index, { oppositeIndex }); } } } } + + private addGameStep( + game: MancalaGame, + index: number, + data: LastStoneInEmptyPitData + ) { + game.addGameStep( + new GameStep(index, GAME_STEP_LAST_STONE_IN_EMPTY_PIT, data) + ); + } } diff --git a/tests/game_rules/GRClearBoardAtEnd.test.ts b/tests/game_rules/GRClearBoardAtEnd.test.ts index b73ef58..369c21f 100644 --- a/tests/game_rules/GRClearBoardAtEnd.test.ts +++ b/tests/game_rules/GRClearBoardAtEnd.test.ts @@ -35,5 +35,12 @@ describe('GRClearBoardAtEnd Test', () => { .map((pit) => pit.stoneCount) .reduce((sum, stoneCount) => sum + stoneCount, 0) ).toBe(0); + expect(game.history[0].gameSteps).toStrictEqual([ + new GameStep(6, GAME_STEP_GAME_MOVE), + new GameStep(6, GAME_STEP_LAST_STONE_IN_BANK), + new GameStep(6, GAME_STEP_BOARD_CLEARED, { + pitIndexesThatHasStone: [12] + }) + ]); }); }); diff --git a/tests/game_rules/GRLastStoneInEmptyPit.test.ts b/tests/game_rules/GRLastStoneInEmptyPit.test.ts new file mode 100644 index 0000000..ed5a6f4 --- /dev/null +++ b/tests/game_rules/GRLastStoneInEmptyPit.test.ts @@ -0,0 +1,27 @@ +import { GAME_STEP_GAME_MOVE } from '../../src/core/MancalaGame'; +import { GameStep } from '../../src/core/HistoryItem'; +import { createGame } from '../TestUtil'; +import { GAME_STEP_LAST_STONE_IN_EMPTY_PIT } from '../../src/common/game_rules/GRLastStoneInEmptyPit'; + +describe('GRClearBoardAtEnd Test', () => { + test('test GRClearBoardAtEnd 1', () => { + const game = createGame(); + const board = game.board; + const initialBoard = [4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 0]; + expect(board.getStoneArray()).toStrictEqual(initialBoard); + game.board.player1Pits[0].stoneCount = 1; + game.board.player1Pits[1].stoneCount = 0; + expect(board.getStoneArray()).toStrictEqual([ + 1, 0, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 0 + ]); + game.moveByPlayerPit('0', 0); + expect(board.getStoneArray()).toStrictEqual([ + 0, 0, 4, 4, 4, 4, 5, 4, 4, 4, 4, 0, 4, 0 + ]); + + expect(game.history[0].gameSteps).toStrictEqual([ + new GameStep(1, GAME_STEP_GAME_MOVE), + new GameStep(1, GAME_STEP_LAST_STONE_IN_EMPTY_PIT, { oppositeIndex: 11 }) + ]); + }); +});