Merge pull request #3 from jhalitaksoy/feature/game-step
Feature/game step
This commit is contained in:
commit
c645f62e91
@ -1,17 +1,52 @@
|
|||||||
|
import { Board } from '../../core/Board';
|
||||||
import { GameRule } from '../../core/GameRule';
|
import { GameRule } from '../../core/GameRule';
|
||||||
|
import { GameStep } from '../../core/HistoryItem';
|
||||||
import { MancalaGame } from '../../core/MancalaGame';
|
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 {
|
export class GRClearBoardAtEnd implements GameRule {
|
||||||
onGameMoveStart(game: MancalaGame, index: number): void {}
|
onGameMoveStart(game: MancalaGame, index: number): void {}
|
||||||
onGameMove(game: MancalaGame, index: number): void {}
|
onGameMove(game: MancalaGame, index: number): void {}
|
||||||
onGameMoveEnd(game: MancalaGame, index: number): void {
|
onGameMoveEnd(game: MancalaGame, index: number): void {
|
||||||
if (game.getPlayer1StoneCountInPits() === 0) {
|
if (game.getPlayer1StoneCountInPits() === 0) {
|
||||||
|
const clearBoardAtEndData = {
|
||||||
|
pitIndexesThatHasStone: this.getPitIndexesThatHasStone(game.board)
|
||||||
|
};
|
||||||
game.board.player1Bank.stoneCount += game.getPlayer2StoneCountInPits();
|
game.board.player1Bank.stoneCount += game.getPlayer2StoneCountInPits();
|
||||||
game.board.clearPlayer2Pits();
|
game.board.clearPlayer2Pits();
|
||||||
}
|
this.addGameStep(game, index, clearBoardAtEndData);
|
||||||
if (game.getPlayer2StoneCountInPits() === 0) {
|
} else if (game.getPlayer2StoneCountInPits() === 0) {
|
||||||
|
const clearBoardAtEndData = {
|
||||||
|
pitIndexesThatHasStone: this.getPitIndexesThatHasStone(game.board)
|
||||||
|
};
|
||||||
game.board.player2Bank.stoneCount += game.getPlayer1StoneCountInPits();
|
game.board.player2Bank.stoneCount += game.getPlayer1StoneCountInPits();
|
||||||
game.board.clearPlayer1Pits();
|
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)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
import { GameRule } from '../../core/GameRule';
|
import { GameRule } from '../../core/GameRule';
|
||||||
|
import { GameStep } from '../../core/HistoryItem';
|
||||||
import { MancalaGame } from '../../core/MancalaGame';
|
import { MancalaGame } from '../../core/MancalaGame';
|
||||||
|
|
||||||
|
export const GAME_STEP_LAST_STONE_IN_BANK = 'GAME_STEP_LAST_STONE_IN_BANK';
|
||||||
|
|
||||||
export class GRLastStoneInBank implements GameRule {
|
export class GRLastStoneInBank implements GameRule {
|
||||||
onGameMoveStart(game: MancalaGame, index: number): void {}
|
onGameMoveStart(game: MancalaGame, index: number): void {}
|
||||||
onGameMove(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 === 'player1Bank' && game.isTurnPlayer1()) ||
|
||||||
(pitType === 'player2Bank' && game.isTurnPlayer2())
|
(pitType === 'player2Bank' && game.isTurnPlayer2())
|
||||||
) {
|
) {
|
||||||
|
game.addGameStep(new GameStep(index, GAME_STEP_LAST_STONE_IN_BANK));
|
||||||
} else {
|
} else {
|
||||||
game.changePlayerTurn();
|
game.changePlayerTurn();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,12 @@
|
|||||||
import { GameRule } from '../../core/GameRule';
|
import { GameRule } from '../../core/GameRule';
|
||||||
|
import { GameStep } from '../../core/HistoryItem';
|
||||||
import { MancalaGame } from '../../core/MancalaGame';
|
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 {
|
export class GRLastStoneInEmptyPit implements GameRule {
|
||||||
onGameMoveStart(game: MancalaGame, index: number): void {}
|
onGameMoveStart(game: MancalaGame, index: number): void {}
|
||||||
onGameMove(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);
|
const pitType = game.board.getPitTypeByIndex(index);
|
||||||
if (pit.stoneCount === 1) {
|
if (pit.stoneCount === 1) {
|
||||||
if (pitType === 'player1Pit' && game.isTurnPlayer1()) {
|
if (pitType === 'player1Pit' && game.isTurnPlayer1()) {
|
||||||
const oppositePit =
|
const oppositeIndex = game.board.getOppositePitIndex(index);
|
||||||
game.board.pits[game.board.getOppositePitIndex(index)];
|
const oppositePit = game.board.pits[oppositeIndex];
|
||||||
if (oppositePit.stoneCount > 0) {
|
if (oppositePit.stoneCount > 0) {
|
||||||
const player1BankIndex =
|
const player1BankIndex =
|
||||||
game.board.pits[game.board.player1BankIndex()];
|
game.board.pits[game.board.player1BankIndex()];
|
||||||
player1BankIndex.stoneCount += 1 + oppositePit.stoneCount;
|
player1BankIndex.stoneCount += 1 + oppositePit.stoneCount;
|
||||||
oppositePit.stoneCount = 0;
|
oppositePit.stoneCount = 0;
|
||||||
pit.stoneCount = 0;
|
pit.stoneCount = 0;
|
||||||
|
this.addGameStep(game, index, { oppositeIndex });
|
||||||
}
|
}
|
||||||
} else if (pitType === 'player2Pit' && game.isTurnPlayer2()) {
|
} else if (pitType === 'player2Pit' && game.isTurnPlayer2()) {
|
||||||
const oppositePit =
|
const oppositeIndex = game.board.getOppositePitIndex(index);
|
||||||
game.board.pits[game.board.getOppositePitIndex(index)];
|
const oppositePit = game.board.pits[oppositeIndex];
|
||||||
if (oppositePit.stoneCount > 0) {
|
if (oppositePit.stoneCount > 0) {
|
||||||
const player2BankIndex =
|
const player2BankIndex =
|
||||||
game.board.pits[game.board.player2BankIndex()];
|
game.board.pits[game.board.player2BankIndex()];
|
||||||
player2BankIndex.stoneCount += 1 + oppositePit.stoneCount;
|
player2BankIndex.stoneCount += 1 + oppositePit.stoneCount;
|
||||||
oppositePit.stoneCount = 0;
|
oppositePit.stoneCount = 0;
|
||||||
pit.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)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,9 +35,9 @@ export class Board {
|
|||||||
for (let index = 0; index < this.totalPitCount(); index++) {
|
for (let index = 0; index < this.totalPitCount(); index++) {
|
||||||
const pitType = this.getPitTypeByIndex(index);
|
const pitType = this.getPitTypeByIndex(index);
|
||||||
if (pitType === 'player1Pit' || pitType === 'player2Pit') {
|
if (pitType === 'player1Pit' || pitType === 'player2Pit') {
|
||||||
pitArray[index] = new Pit(initialStoneCountInPits);
|
pitArray[index] = new Pit(index, initialStoneCountInPits);
|
||||||
} else if (pitType === 'player1Bank' || pitType === 'player2Bank') {
|
} else if (pitType === 'player1Bank' || pitType === 'player2Bank') {
|
||||||
pitArray[index] = new Bank(0);
|
pitArray[index] = new Bank(index, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pitArray;
|
return pitArray;
|
||||||
@ -83,6 +83,18 @@ export class Board {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public checkPitTypeIsNormalPitByIndex(index: number): boolean {
|
||||||
|
this.checkIndeAndMaybeThrowError(index);
|
||||||
|
const pitType = this.getPitTypeByIndex(index);
|
||||||
|
return pitType === 'player1Pit' || pitType === 'player2Pit';
|
||||||
|
}
|
||||||
|
|
||||||
|
public checkPitTypeIsBankByIndex(index: number): boolean {
|
||||||
|
this.checkIndeAndMaybeThrowError(index);
|
||||||
|
const pitType = this.getPitTypeByIndex(index);
|
||||||
|
return pitType === 'player1Bank' || pitType === 'player2Bank';
|
||||||
|
}
|
||||||
|
|
||||||
public move(index: number) {
|
public move(index: number) {
|
||||||
this.checkIndeAndMaybeThrowError(index);
|
this.checkIndeAndMaybeThrowError(index);
|
||||||
const pitType = this.getPitTypeByIndex(index);
|
const pitType = this.getPitTypeByIndex(index);
|
||||||
|
|||||||
@ -1,16 +1,34 @@
|
|||||||
export class HistoryItem {
|
export class HistoryItem {
|
||||||
boardSnapshot: number[];
|
boardSnapshot: number[];
|
||||||
constructor(boardSnapshot: number[]) {
|
gameSteps: GameStep[];
|
||||||
|
constructor(boardSnapshot: number[], gameSteps: GameStep[]) {
|
||||||
this.boardSnapshot = boardSnapshot;
|
this.boardSnapshot = boardSnapshot;
|
||||||
|
this.gameSteps = gameSteps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MoveHistoryItem extends HistoryItem {
|
export class MoveHistoryItem extends HistoryItem {
|
||||||
playerId: string;
|
playerId: string;
|
||||||
moveIndex: number;
|
moveIndex: number;
|
||||||
constructor(playerId: string, moveIndex: number, boardSnapshot: number[]) {
|
constructor(
|
||||||
super(boardSnapshot);
|
playerId: string,
|
||||||
|
moveIndex: number,
|
||||||
|
boardSnapshot: number[],
|
||||||
|
gameSteps: GameStep[]
|
||||||
|
) {
|
||||||
|
super(boardSnapshot, gameSteps);
|
||||||
this.playerId = playerId;
|
this.playerId = playerId;
|
||||||
this.moveIndex = moveIndex;
|
this.moveIndex = moveIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class GameStep {
|
||||||
|
index: number;
|
||||||
|
type: string;
|
||||||
|
data: any | null;
|
||||||
|
constructor(index: number, type: string, data: any = null) {
|
||||||
|
this.index = index;
|
||||||
|
this.type = type;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
import { Board, PitType } from './Board';
|
import { Board, PitType } from './Board';
|
||||||
import { GameRule } from './GameRule';
|
import { GameRule } from './GameRule';
|
||||||
import { HistoryItem, MoveHistoryItem } from './HistoryItem';
|
import { HistoryItem, MoveHistoryItem, GameStep } from './HistoryItem';
|
||||||
|
|
||||||
export type GameState = 'initial' | 'playing' | 'ended';
|
export type GameState = 'initial' | 'playing' | 'ended';
|
||||||
|
|
||||||
|
export const GAME_STEP_GAME_MOVE = 'GAME_STEP_GAME_MOVE';
|
||||||
|
|
||||||
export class MancalaGame {
|
export class MancalaGame {
|
||||||
id: string;
|
id: string;
|
||||||
board: Board;
|
board: Board;
|
||||||
@ -13,6 +15,7 @@ export class MancalaGame {
|
|||||||
state: GameState;
|
state: GameState;
|
||||||
gameRules: GameRule[];
|
gameRules: GameRule[];
|
||||||
history: HistoryItem[];
|
history: HistoryItem[];
|
||||||
|
currentHistoryItem: HistoryItem | null = null;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
id: string,
|
id: string,
|
||||||
@ -42,6 +45,7 @@ export class MancalaGame {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
this.board.onGameMove = (index: number) => {
|
this.board.onGameMove = (index: number) => {
|
||||||
|
this.addGameStep(new GameStep(index, GAME_STEP_GAME_MOVE));
|
||||||
this.gameRules.forEach((gameRule) => {
|
this.gameRules.forEach((gameRule) => {
|
||||||
gameRule.onGameMove(this, index);
|
gameRule.onGameMove(this, index);
|
||||||
});
|
});
|
||||||
@ -131,10 +135,15 @@ export class MancalaGame {
|
|||||||
}
|
}
|
||||||
if (this.canPlayerMove(playerId, pitIndex)) {
|
if (this.canPlayerMove(playerId, pitIndex)) {
|
||||||
const moveIndex = this.getBoardIndexByPlayerId(playerId, pitIndex);
|
const moveIndex = this.getBoardIndexByPlayerId(playerId, pitIndex);
|
||||||
this.board.move(moveIndex);
|
this.currentHistoryItem = new MoveHistoryItem(
|
||||||
this.history.push(
|
playerId,
|
||||||
new MoveHistoryItem(playerId, moveIndex, this.board.getStoneArray())
|
moveIndex,
|
||||||
|
[],
|
||||||
|
[]
|
||||||
);
|
);
|
||||||
|
this.board.move(moveIndex);
|
||||||
|
this.currentHistoryItem.boardSnapshot = this.board.getStoneArray();
|
||||||
|
this.history.push(this.currentHistoryItem);
|
||||||
if (this.checkGameIsEnded()) {
|
if (this.checkGameIsEnded()) {
|
||||||
this.state = 'ended';
|
this.state = 'ended';
|
||||||
}
|
}
|
||||||
@ -218,4 +227,12 @@ export class MancalaGame {
|
|||||||
mancalaGame.state
|
mancalaGame.state
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getCurrentHistoryItem(): HistoryItem | null {
|
||||||
|
return this.currentHistoryItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addGameStep(gameStep: GameStep) {
|
||||||
|
this.getCurrentHistoryItem()?.gameSteps.push(gameStep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
export class Pit {
|
export class Pit {
|
||||||
|
index: number;
|
||||||
stoneCount: number;
|
stoneCount: number;
|
||||||
|
|
||||||
constructor(stoneCount = 0) {
|
constructor(index: number, stoneCount = 0) {
|
||||||
|
this.index = index;
|
||||||
this.stoneCount = stoneCount;
|
this.stoneCount = stoneCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,8 +21,8 @@ export class Pit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Bank extends Pit {
|
export class Bank extends Pit {
|
||||||
constructor(stoneCount = 0) {
|
constructor(index: number, stoneCount = 0) {
|
||||||
super(stoneCount);
|
super(index, stoneCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
override get isBank(): boolean {
|
override get isBank(): boolean {
|
||||||
|
|||||||
@ -1,6 +1,23 @@
|
|||||||
import { Board } from '../src/core/Board';
|
import { Board } from '../src/core/Board';
|
||||||
|
|
||||||
describe('Board Test', () => {
|
describe('Board Test', () => {
|
||||||
|
test('test pit index', () => {
|
||||||
|
const board = new Board(6, 4);
|
||||||
|
expect(board.pits[0].index).toBe(0);
|
||||||
|
expect(board.pits[1].index).toBe(1);
|
||||||
|
expect(board.pits[2].index).toBe(2);
|
||||||
|
expect(board.pits[3].index).toBe(3);
|
||||||
|
expect(board.pits[4].index).toBe(4);
|
||||||
|
expect(board.pits[5].index).toBe(5);
|
||||||
|
expect(board.pits[6].index).toBe(6);
|
||||||
|
expect(board.pits[7].index).toBe(7);
|
||||||
|
expect(board.pits[8].index).toBe(8);
|
||||||
|
expect(board.pits[9].index).toBe(9);
|
||||||
|
expect(board.pits[10].index).toBe(10);
|
||||||
|
expect(board.pits[11].index).toBe(11);
|
||||||
|
expect(board.pits[12].index).toBe(12);
|
||||||
|
expect(board.pits[13].index).toBe(13);
|
||||||
|
});
|
||||||
test('test getPitTypeByIndex', () => {
|
test('test getPitTypeByIndex', () => {
|
||||||
const board = new Board(6, 4);
|
const board = new Board(6, 4);
|
||||||
expect(board.getPitTypeByIndex(0)).toBe('player1Pit');
|
expect(board.getPitTypeByIndex(0)).toBe('player1Pit');
|
||||||
|
|||||||
@ -1,29 +1,6 @@
|
|||||||
import { GRClearBoardAtEnd } from '../src/common/game_rules/GRClearBoardAtEnd';
|
import { GameStep, MoveHistoryItem } from '../src/core/HistoryItem';
|
||||||
import { GRLastStoneInBank } from '../src/common/game_rules/GRLastStoneInBank';
|
import { GAME_STEP_GAME_MOVE, MancalaGame } from '../src/core/MancalaGame';
|
||||||
import { GRLastStoneInEmptyPit } from '../src/common/game_rules/GRLastStoneInEmptyPit';
|
import { createGame } from './TestUtil';
|
||||||
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()
|
|
||||||
],
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
return game;
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('Game Test', () => {
|
describe('Game Test', () => {
|
||||||
test('test getPlayerIdByIndex', () => {
|
test('test getPlayerIdByIndex', () => {
|
||||||
@ -125,27 +102,55 @@ describe('Game Test', () => {
|
|||||||
game.moveByPlayerPit(player2Id, 0);
|
game.moveByPlayerPit(player2Id, 0);
|
||||||
game.moveByPlayerPit(player1Id, 1);
|
game.moveByPlayerPit(player1Id, 1);
|
||||||
game.moveByPlayerPit(player2Id, 1);
|
game.moveByPlayerPit(player2Id, 1);
|
||||||
expect(game.history).toStrictEqual([
|
const historyItem1 = new MoveHistoryItem(
|
||||||
new MoveHistoryItem(
|
player1Id,
|
||||||
player1Id,
|
0,
|
||||||
0,
|
[1, 5, 5, 5, 4, 4, 0, 4, 4, 4, 4, 4, 4, 0],
|
||||||
[1, 5, 5, 5, 4, 4, 0, 4, 4, 4, 4, 4, 4, 0]
|
[
|
||||||
),
|
new GameStep(0, GAME_STEP_GAME_MOVE),
|
||||||
new MoveHistoryItem(
|
new GameStep(1, GAME_STEP_GAME_MOVE),
|
||||||
player2Id,
|
new GameStep(2, GAME_STEP_GAME_MOVE),
|
||||||
7,
|
new GameStep(3, GAME_STEP_GAME_MOVE)
|
||||||
[1, 5, 5, 5, 4, 4, 0, 1, 5, 5, 5, 4, 4, 0]
|
]
|
||||||
),
|
);
|
||||||
new MoveHistoryItem(
|
const historyItem2 = new MoveHistoryItem(
|
||||||
player1Id,
|
player2Id,
|
||||||
1,
|
7,
|
||||||
[1, 1, 6, 6, 5, 5, 0, 1, 5, 5, 5, 4, 4, 0]
|
[1, 5, 5, 5, 4, 4, 0, 1, 5, 5, 5, 4, 4, 0],
|
||||||
),
|
[
|
||||||
new MoveHistoryItem(
|
new GameStep(7, GAME_STEP_GAME_MOVE),
|
||||||
player2Id,
|
new GameStep(8, GAME_STEP_GAME_MOVE),
|
||||||
8,
|
new GameStep(9, GAME_STEP_GAME_MOVE),
|
||||||
[1, 1, 6, 6, 5, 5, 0, 1, 1, 6, 6, 5, 5, 0]
|
new GameStep(10, GAME_STEP_GAME_MOVE)
|
||||||
)
|
]
|
||||||
]);
|
);
|
||||||
|
const historyItem3 = new MoveHistoryItem(
|
||||||
|
player1Id,
|
||||||
|
1,
|
||||||
|
[1, 1, 6, 6, 5, 5, 0, 1, 5, 5, 5, 4, 4, 0],
|
||||||
|
[
|
||||||
|
new GameStep(1, GAME_STEP_GAME_MOVE),
|
||||||
|
new GameStep(2, GAME_STEP_GAME_MOVE),
|
||||||
|
new GameStep(3, GAME_STEP_GAME_MOVE),
|
||||||
|
new GameStep(4, GAME_STEP_GAME_MOVE),
|
||||||
|
new GameStep(5, GAME_STEP_GAME_MOVE)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
const historyItem4 = new MoveHistoryItem(
|
||||||
|
player2Id,
|
||||||
|
8,
|
||||||
|
[1, 1, 6, 6, 5, 5, 0, 1, 1, 6, 6, 5, 5, 0],
|
||||||
|
[
|
||||||
|
new GameStep(8, GAME_STEP_GAME_MOVE),
|
||||||
|
new GameStep(9, GAME_STEP_GAME_MOVE),
|
||||||
|
new GameStep(10, GAME_STEP_GAME_MOVE),
|
||||||
|
new GameStep(11, GAME_STEP_GAME_MOVE),
|
||||||
|
new GameStep(12, GAME_STEP_GAME_MOVE)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
expect(game.history[0]).toStrictEqual(historyItem1);
|
||||||
|
expect(game.history[1]).toStrictEqual(historyItem2);
|
||||||
|
expect(game.history[2]).toStrictEqual(historyItem3);
|
||||||
|
expect(game.history[3]).toStrictEqual(historyItem4);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
25
tests/TestUtil.ts
Normal file
25
tests/TestUtil.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
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 { MancalaGame } from '../src/core/MancalaGame';
|
||||||
|
|
||||||
|
export 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()
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
return game;
|
||||||
|
}
|
||||||
@ -1,28 +1,19 @@
|
|||||||
import { GRLastStoneInBank } from '../../src/common/game_rules/GRLastStoneInBank';
|
import {
|
||||||
import { GRLastStoneInEmptyPit } from '../../src/common/game_rules/GRLastStoneInEmptyPit';
|
GAME_STEP_LAST_STONE_IN_BANK,
|
||||||
import { GRClearBoardAtEnd } from '../../src/common/game_rules/GRClearBoardAtEnd';
|
GRLastStoneInBank
|
||||||
|
} from '../../src/common/game_rules/GRLastStoneInBank';
|
||||||
|
import {
|
||||||
|
GAME_STEP_LAST_STONE_IN_EMPTY_PIT,
|
||||||
|
GRLastStoneInEmptyPit
|
||||||
|
} from '../../src/common/game_rules/GRLastStoneInEmptyPit';
|
||||||
|
import {
|
||||||
|
GAME_STEP_BOARD_CLEARED,
|
||||||
|
GRClearBoardAtEnd
|
||||||
|
} from '../../src/common/game_rules/GRClearBoardAtEnd';
|
||||||
import { Board } from '../../src/core/Board';
|
import { Board } from '../../src/core/Board';
|
||||||
import { MancalaGame } from '../../src/core/MancalaGame';
|
import { GAME_STEP_GAME_MOVE, MancalaGame } from '../../src/core/MancalaGame';
|
||||||
|
import { GameStep } from '../../src/core/HistoryItem';
|
||||||
function createGame(): MancalaGame {
|
import { createGame } from '../TestUtil';
|
||||||
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()
|
|
||||||
],
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
return game;
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('GRClearBoardAtEnd Test', () => {
|
describe('GRClearBoardAtEnd Test', () => {
|
||||||
test('test GRClearBoardAtEnd 1', () => {
|
test('test GRClearBoardAtEnd 1', () => {
|
||||||
@ -44,5 +35,12 @@ describe('GRClearBoardAtEnd Test', () => {
|
|||||||
.map((pit) => pit.stoneCount)
|
.map((pit) => pit.stoneCount)
|
||||||
.reduce((sum, stoneCount) => sum + stoneCount, 0)
|
.reduce((sum, stoneCount) => sum + stoneCount, 0)
|
||||||
).toBe(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]
|
||||||
|
})
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
27
tests/game_rules/GRLastStoneInEmptyPit.test.ts
Normal file
27
tests/game_rules/GRLastStoneInEmptyPit.test.ts
Normal file
@ -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 })
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user