refactor: update boop implementation
This commit is contained in:
+41
-20
@@ -12,17 +12,20 @@ type BoopPart = Part & { player: PlayerType; pieceType: PieceType };
|
||||
|
||||
type PieceSupply = { supply: number; placed: number };
|
||||
|
||||
type PlayerSupply = {
|
||||
type Player = {
|
||||
id: PlayerType;
|
||||
kitten: PieceSupply;
|
||||
cat: PieceSupply;
|
||||
};
|
||||
|
||||
// TODO refactor this into an Entity
|
||||
function createPlayerSupply(): PlayerSupply {
|
||||
return {
|
||||
type PlayerEntity = Entity<Player>;
|
||||
|
||||
function createPlayer(id: PlayerType): PlayerEntity {
|
||||
return entity<Player>(id, {
|
||||
id,
|
||||
kitten: { supply: MAX_PIECES_PER_PLAYER, placed: 0 },
|
||||
cat: { supply: 0, placed: 0 },
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function createInitialState() {
|
||||
@@ -38,8 +41,8 @@ export function createInitialState() {
|
||||
currentPlayer: 'white' as PlayerType,
|
||||
winner: null as WinnerType,
|
||||
players: {
|
||||
white: createPlayerSupply(),
|
||||
black: createPlayerSupply(),
|
||||
white: createPlayer('white'),
|
||||
black: createPlayer('black'),
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -47,6 +50,24 @@ export type BoopState = ReturnType<typeof createInitialState>;
|
||||
const registration = createGameCommandRegistry<BoopState>();
|
||||
export const registry = registration.registry;
|
||||
|
||||
// Player Entity helper functions
|
||||
export function getPlayer(host: Entity<BoopState>, player: PlayerType): PlayerEntity {
|
||||
return host.value.players[player];
|
||||
}
|
||||
|
||||
export function decrementSupply(player: PlayerEntity, pieceType: PieceType) {
|
||||
player.produce(p => {
|
||||
p[pieceType].supply--;
|
||||
p[pieceType].placed++;
|
||||
});
|
||||
}
|
||||
|
||||
export function incrementSupply(player: PlayerEntity, pieceType: PieceType, count?: number) {
|
||||
player.produce(p => {
|
||||
p[pieceType].supply += count ?? 1;
|
||||
});
|
||||
}
|
||||
|
||||
registration.add('setup', async function() {
|
||||
const {context} = this;
|
||||
while (true) {
|
||||
@@ -85,7 +106,8 @@ registration.add('turn <player>', async function(cmd) {
|
||||
return `Cell (${row}, ${col}) is already occupied.`;
|
||||
}
|
||||
|
||||
const supply = this.context.value.players[player][pieceType].supply;
|
||||
const playerEntity = getPlayer(this.context, player);
|
||||
const supply = playerEntity.value[pieceType].supply;
|
||||
if (supply <= 0) {
|
||||
return `No ${pieceType}s left in ${player}'s supply.`;
|
||||
}
|
||||
@@ -129,7 +151,8 @@ export function getPartAt(host: Entity<BoopState>, row: number, col: number): En
|
||||
|
||||
export function placePiece(host: Entity<BoopState>, row: number, col: number, player: PlayerType, pieceType: PieceType) {
|
||||
const board = getBoardRegion(host);
|
||||
const count = host.value.players[player][pieceType].placed + 1;
|
||||
const playerEntity = getPlayer(host, player);
|
||||
const count = playerEntity.value[pieceType].placed + 1;
|
||||
|
||||
const piece: BoopPart = {
|
||||
id: `${player}-${pieceType}-${count}`,
|
||||
@@ -140,12 +163,11 @@ export function placePiece(host: Entity<BoopState>, row: number, col: number, pl
|
||||
};
|
||||
host.produce(s => {
|
||||
const e = entity(piece.id, piece);
|
||||
s.players[player][pieceType].supply--;
|
||||
s.players[player][pieceType].placed++;
|
||||
board.produce(draft => {
|
||||
draft.children.push(e);
|
||||
});
|
||||
});
|
||||
decrementSupply(playerEntity, pieceType);
|
||||
}
|
||||
|
||||
export function applyBoops(host: Entity<BoopState>, placedRow: number, placedCol: number, placedType: PieceType) {
|
||||
@@ -180,10 +202,9 @@ export function applyBoops(host: Entity<BoopState>, placedRow: number, placedCol
|
||||
if (newRow < 0 || newRow >= BOARD_SIZE || newCol < 0 || newCol >= BOARD_SIZE) {
|
||||
const pt = part.value.pieceType;
|
||||
const pl = part.value.player;
|
||||
const playerEntity = getPlayer(host, pl);
|
||||
removePieceFromBoard(host, part);
|
||||
host.produce(state => {
|
||||
state.players[pl][pt].supply++;
|
||||
});
|
||||
incrementSupply(playerEntity, pt);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -298,9 +319,8 @@ export function processGraduation(host: Entity<BoopState>, player: PlayerType, l
|
||||
}
|
||||
|
||||
const count = partsToRemove.length;
|
||||
host.produce(state => {
|
||||
state.players[player].cat.supply += count;
|
||||
});
|
||||
const playerEntity = getPlayer(host, player);
|
||||
incrementSupply(playerEntity, 'cat', count);
|
||||
}
|
||||
|
||||
export function checkWinner(host: Entity<BoopState>): WinnerType {
|
||||
@@ -318,9 +338,10 @@ export function checkWinner(host: Entity<BoopState>): WinnerType {
|
||||
if (hasWinningLine(positions)) return player;
|
||||
}
|
||||
|
||||
const state = host.value;
|
||||
const whiteTotal = MAX_PIECES_PER_PLAYER - state.players.white.kitten.supply + state.players.white.cat.supply;
|
||||
const blackTotal = MAX_PIECES_PER_PLAYER - state.players.black.kitten.supply + state.players.black.cat.supply;
|
||||
const whitePlayer = getPlayer(host, 'white');
|
||||
const blackPlayer = getPlayer(host, 'black');
|
||||
const whiteTotal = MAX_PIECES_PER_PLAYER - whitePlayer.value.kitten.supply + whitePlayer.value.cat.supply;
|
||||
const blackTotal = MAX_PIECES_PER_PLAYER - blackPlayer.value.kitten.supply + blackPlayer.value.cat.supply;
|
||||
|
||||
if (whiteTotal >= MAX_PIECES_PER_PLAYER && blackTotal >= MAX_PIECES_PER_PLAYER) {
|
||||
return 'draw';
|
||||
|
||||
Reference in New Issue
Block a user