update MancalaGame and Board
This commit is contained in:
parent
81a74a416e
commit
ed6787f2e6
@ -17,10 +17,16 @@ export class Board {
|
|||||||
onGameMove: (index: number) => void = () => {};
|
onGameMove: (index: number) => void = () => {};
|
||||||
onGameMoveEnd: (index: number) => void = () => {};
|
onGameMoveEnd: (index: number) => void = () => {};
|
||||||
|
|
||||||
constructor(playerPitCount: number, initialStoneCountInPits: number) {
|
constructor(
|
||||||
|
playerPitCount: number,
|
||||||
|
initialStoneCountInPits: number,
|
||||||
|
pits: Pit[] | null = null
|
||||||
|
) {
|
||||||
this.playerPitCount = playerPitCount;
|
this.playerPitCount = playerPitCount;
|
||||||
this.initialStoneCountInPits = initialStoneCountInPits;
|
this.initialStoneCountInPits = initialStoneCountInPits;
|
||||||
this.pits = this.createPits(playerPitCount, initialStoneCountInPits);
|
this.pits = pits
|
||||||
|
? pits
|
||||||
|
: this.createPits(playerPitCount, initialStoneCountInPits);
|
||||||
}
|
}
|
||||||
|
|
||||||
createPits(playerPitCount: number, initialStoneCountInPits: number): Pit[] {
|
createPits(playerPitCount: number, initialStoneCountInPits: number): Pit[] {
|
||||||
@ -140,4 +146,57 @@ export class Board {
|
|||||||
public getStoneArray(): number[] {
|
public getStoneArray(): number[] {
|
||||||
return [...this.pits.map((pit) => pit.stoneCount)];
|
return [...this.pits.map((pit) => pit.stoneCount)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get player1Pits(): Pit[] {
|
||||||
|
return this.pits.slice(
|
||||||
|
this.player1PitStartIndex(),
|
||||||
|
this.player1BankIndex()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
get player2Pits(): Pit[] {
|
||||||
|
return this.pits.slice(
|
||||||
|
this.player2PitStartIndex(),
|
||||||
|
this.player2BankIndex()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
get player1Bank(): Bank {
|
||||||
|
return this.pits[this.player1BankIndex()];
|
||||||
|
}
|
||||||
|
|
||||||
|
get player2Bank(): Bank {
|
||||||
|
return this.pits[this.player2BankIndex()];
|
||||||
|
}
|
||||||
|
|
||||||
|
public getOppositePitIndex(index: number) {
|
||||||
|
if (index > this.player1BankIndex()) {
|
||||||
|
return this.player2PitStopIndex() - index;
|
||||||
|
} else {
|
||||||
|
return this.player1BankIndex() + this.playerPitCount - index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public clear() {
|
||||||
|
this.player1Bank.stoneCount = 0;
|
||||||
|
this.player2Bank.stoneCount = 0;
|
||||||
|
this.clearPlayer1Pits();
|
||||||
|
this.clearPlayer2Pits();
|
||||||
|
}
|
||||||
|
|
||||||
|
public clearPlayer1Pits() {
|
||||||
|
this.fillPlayer1Pits(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public clearPlayer2Pits() {
|
||||||
|
this.fillPlayer2Pits(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public fillPlayer1Pits(stoneCount: number) {
|
||||||
|
this.player1Pits.forEach((pit) => (pit.stoneCount = stoneCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
public fillPlayer2Pits(stoneCount: number) {
|
||||||
|
this.player2Pits.forEach((pit) => (pit.stoneCount = stoneCount));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,29 +1,29 @@
|
|||||||
import { Board, PitType } from './Board';
|
import { Board, PitType } from './Board';
|
||||||
import { GameRule } from './GameRule';
|
import { GameRule } from './GameRule';
|
||||||
import { Player } from './Player';
|
|
||||||
|
|
||||||
export type GameState = 'initial' | 'playing' | 'ended';
|
export type GameState = 'initial' | 'playing' | 'ended';
|
||||||
|
|
||||||
export class MancalaGame {
|
export class MancalaGame {
|
||||||
board: Board;
|
board: Board;
|
||||||
player1: Player;
|
player1Id: string;
|
||||||
player2: Player;
|
player2Id: string;
|
||||||
turnPlayerId: string;
|
turnPlayerId: string;
|
||||||
state: GameState;
|
state: GameState;
|
||||||
gameRules: GameRule[];
|
gameRules: GameRule[];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
board: Board,
|
board: Board,
|
||||||
player1: Player,
|
player1Id: string,
|
||||||
player2: Player,
|
player2Id: string,
|
||||||
turnPlayerId: string,
|
turnPlayerId: string,
|
||||||
gameRules: GameRule[]
|
gameRules: GameRule[],
|
||||||
|
state: GameState = 'initial'
|
||||||
) {
|
) {
|
||||||
this.board = board;
|
this.board = board;
|
||||||
this.player1 = player1;
|
this.player1Id = player1Id;
|
||||||
this.player2 = player2;
|
this.player2Id = player2Id;
|
||||||
this.turnPlayerId = turnPlayerId;
|
this.turnPlayerId = turnPlayerId;
|
||||||
this.state = 'initial';
|
this.state = state;
|
||||||
this.gameRules = gameRules;
|
this.gameRules = gameRules;
|
||||||
this.listenBoardMoveEvents();
|
this.listenBoardMoveEvents();
|
||||||
}
|
}
|
||||||
@ -47,89 +47,92 @@ export class MancalaGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
changePlayerTurn() {
|
changePlayerTurn() {
|
||||||
if (this.turnPlayerId === this.player1.id) {
|
if (this.turnPlayerId === this.player1Id) {
|
||||||
this.turnPlayerId = this.player2.id;
|
this.turnPlayerId = this.player2Id;
|
||||||
} else {
|
} else {
|
||||||
this.turnPlayerId = this.player1.id;
|
this.turnPlayerId = this.player1Id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isTurnPlayer1() {
|
isTurnPlayer1() {
|
||||||
return this.player1.id === this.turnPlayerId;
|
return this.player1Id === this.turnPlayerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
isTurnPlayer2() {
|
isTurnPlayer2() {
|
||||||
return this.player2.id === this.turnPlayerId;
|
return this.player2Id === this.turnPlayerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
getPlayerByPitType(pitType: PitType): Player {
|
getPlayerIdByPitType(pitType: PitType): string {
|
||||||
if (pitType === 'player1Pit' || pitType === 'player1Bank') {
|
if (pitType === 'player1Pit' || pitType === 'player1Bank') {
|
||||||
return this.player1;
|
return this.player1Id;
|
||||||
} else if (pitType === 'player2Pit' || pitType === 'player2Bank') {
|
} else if (pitType === 'player2Pit' || pitType === 'player2Bank') {
|
||||||
return this.player2;
|
return this.player2Id;
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Unknown pit type : ' + pitType);
|
throw new Error('Unknown pit type : ' + pitType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getPlayerByIndex(index: number): Player {
|
getPlayerIdByIndex(index: number): string {
|
||||||
const pitType = this.board.getPitTypeByIndex(index);
|
const pitType = this.board.getPitTypeByIndex(index);
|
||||||
return this.getPlayerByPitType(pitType);
|
return this.getPlayerIdByPitType(pitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkIsPlayerTurnByIndex(index: number): boolean {
|
checkIsPlayerTurnByIndex(index: number): boolean {
|
||||||
const player = this.getPlayerByIndex(index);
|
const playerId = this.getPlayerIdByIndex(index);
|
||||||
return this.checkIsPlayerTurn(player);
|
return this.checkIsPlayerTurn(playerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
getBoardIndexByPlayer(player: Player, pitIndex: number) {
|
getBoardIndexByPlayerId(playerId: string, pitIndex: number) {
|
||||||
if (this.player1.id === player.id) {
|
if (this.player1Id === playerId) {
|
||||||
return this.board.player1PitStartIndex() + pitIndex;
|
return this.board.player1PitStartIndex() + pitIndex;
|
||||||
} else if (this.player2.id === player.id) {
|
} else if (this.player2Id === playerId) {
|
||||||
return this.board.player2PitStartIndex() + pitIndex;
|
return this.board.player2PitStartIndex() + pitIndex;
|
||||||
} else {
|
} else {
|
||||||
return -1; // throwing an error might be better
|
return -1; // throwing an error might be better
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public checkIsPlayerTurn(player: Player) {
|
public checkIsPlayerTurn(playerId: string) {
|
||||||
return player.id === this.turnPlayerId;
|
return playerId === this.turnPlayerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public checkPitIndexForPlayer(player: Player, pitIndex: number) {
|
public checkPitIndexForPlayerId(playerId: string, pitIndex: number) {
|
||||||
const foundPlayer = this.getPlayerByIndex(
|
const foundPlayerId = this.getPlayerIdByIndex(
|
||||||
this.getBoardIndexByPlayer(player, pitIndex)
|
this.getBoardIndexByPlayerId(playerId, pitIndex)
|
||||||
);
|
);
|
||||||
return player.id === foundPlayer.id;
|
return playerId === foundPlayerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public checkIsPitIndexBank(player: Player, pitIndex: number) {
|
public checkIsPitIndexBank(playerId: string, pitIndex: number) {
|
||||||
const pitType = this.board.getPitTypeByIndex(
|
const pitType = this.board.getPitTypeByIndex(
|
||||||
this.getBoardIndexByPlayer(player, pitIndex)
|
this.getBoardIndexByPlayerId(playerId, pitIndex)
|
||||||
);
|
);
|
||||||
return pitType === 'player1Bank' || pitType === 'player2Bank';
|
return pitType === 'player1Bank' || pitType === 'player2Bank';
|
||||||
}
|
}
|
||||||
|
|
||||||
public canPlayerMove(player: Player, pitIndex: number) {
|
public canPlayerMove(playerId: string, pitIndex: number) {
|
||||||
const isPitIndexCorrect = this.checkPitIndexForPlayer(player, pitIndex);
|
const isPitIndexCorrect = this.checkPitIndexForPlayerId(playerId, pitIndex);
|
||||||
const isPitIndexBank = this.checkIsPitIndexBank(player, pitIndex);
|
const isPitIndexBank = this.checkIsPitIndexBank(playerId, pitIndex);
|
||||||
const isPlayerTurn = this.checkIsPlayerTurn(player);
|
const isPlayerTurn = this.checkIsPlayerTurn(playerId);
|
||||||
return isPitIndexCorrect && !isPitIndexBank && isPlayerTurn;
|
return isPitIndexCorrect && !isPitIndexBank && isPlayerTurn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public moveByPlayerPit(player: Player, pitIndex: number) {
|
public moveByPlayerPit(playerId: string, pitIndex: number) {
|
||||||
if (this.state === 'ended') return;
|
if (this.state === 'ended') return;
|
||||||
if (this.state === 'initial') {
|
if (this.state === 'initial') {
|
||||||
this.state = 'playing';
|
this.state = 'playing';
|
||||||
}
|
}
|
||||||
if (this.canPlayerMove(player, pitIndex)) {
|
if (this.canPlayerMove(playerId, pitIndex)) {
|
||||||
this.board.move(this.getBoardIndexByPlayer(player, pitIndex));
|
this.board.move(this.getBoardIndexByPlayerId(playerId, pitIndex));
|
||||||
if (this.checkGameIsEnded()) {
|
if (this.checkGameIsEnded()) {
|
||||||
this.state = 'ended';
|
this.state = 'ended';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const isPitIndexCorrect = this.checkPitIndexForPlayer(player, pitIndex);
|
const isPitIndexCorrect = this.checkPitIndexForPlayerId(
|
||||||
const isPlayerTurn = this.checkIsPlayerTurn(player);
|
playerId,
|
||||||
|
pitIndex
|
||||||
|
);
|
||||||
|
const isPlayerTurn = this.checkIsPlayerTurn(playerId);
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Player cannot move reason : isPitIndexCorrect = ${isPitIndexCorrect} isPlayerTurn = ${isPlayerTurn}`
|
`Player cannot move reason : isPitIndexCorrect = ${isPitIndexCorrect} isPlayerTurn = ${isPlayerTurn}`
|
||||||
);
|
);
|
||||||
@ -165,7 +168,7 @@ export class MancalaGame {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkGameIsEnded(): boolean {
|
public checkGameIsEnded(): boolean {
|
||||||
if (
|
if (
|
||||||
this.getPlayer1StoneCountInPits() === 0 ||
|
this.getPlayer1StoneCountInPits() === 0 ||
|
||||||
this.getPlayer2StoneCountInPits() === 0
|
this.getPlayer2StoneCountInPits() === 0
|
||||||
@ -174,4 +177,32 @@ export class MancalaGame {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getWonPlayerId(): string | null {
|
||||||
|
if (this.checkGameIsEnded()) {
|
||||||
|
if (
|
||||||
|
this.board.player1Bank.stoneCount > this.board.player2Bank.stoneCount
|
||||||
|
) {
|
||||||
|
return this.player1Id;
|
||||||
|
} else {
|
||||||
|
return this.player2Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static createFromMancalaGame(mancalaGame: MancalaGame): MancalaGame {
|
||||||
|
return new MancalaGame(
|
||||||
|
new Board(
|
||||||
|
mancalaGame.board.playerPitCount,
|
||||||
|
mancalaGame.board.initialStoneCountInPits,
|
||||||
|
mancalaGame.board.pits
|
||||||
|
),
|
||||||
|
mancalaGame.player1Id,
|
||||||
|
mancalaGame.player2Id,
|
||||||
|
mancalaGame.turnPlayerId,
|
||||||
|
mancalaGame.gameRules,
|
||||||
|
mancalaGame.state
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user