refactor: update usage pattern for tic tac toe and boop

This commit is contained in:
hyper
2026-04-02 19:32:07 +08:00
parent 5f812a3478
commit 15122defcc
4 changed files with 74 additions and 72 deletions
+32 -23
View File
@@ -17,6 +17,7 @@ type PlayerSupply = {
cat: PieceSupply;
};
// TODO refactor this into an Entity
function createPlayerSupply(): PlayerSupply {
return {
kitten: { supply: MAX_PIECES_PER_PLAYER, placed: 0 },
@@ -67,37 +68,45 @@ registration.add('setup', async function() {
registration.add('turn <player>', async function(cmd) {
const [turnPlayer] = cmd.params as [PlayerType];
const maxRetries = 50;
let retries = 0;
while (retries < maxRetries) {
retries++;
const playCmd = await this.prompt('play <player> <row:number> <col:number> [type:string]');
const [player, row, col, type] = playCmd.params as [PlayerType, number, number, PieceType?];
const pieceType = type === 'cat' ? 'cat' : 'kitten';
const playCmd = await this.prompt(
'play <player> <row:number> <col:number> [type:string]',
(command) => {
const [player, row, col, type] = command.params as [PlayerType, number, number, PieceType?];
const pieceType = type === 'cat' ? 'cat' : 'kitten';
if (player !== turnPlayer) continue;
if (!isValidMove(row, col)) continue;
if (isCellOccupied(this.context, row, col)) continue;
if (player !== turnPlayer) {
return `Invalid player: ${player}. Expected ${turnPlayer}.`;
}
if (!isValidMove(row, col)) {
return `Invalid position: (${row}, ${col}). Must be between 0 and ${BOARD_SIZE - 1}.`;
}
if (isCellOccupied(this.context, row, col)) {
return `Cell (${row}, ${col}) is already occupied.`;
}
const supply = this.context.value.players[player][pieceType].supply;
if (supply <= 0) continue;
placePiece(this.context, row, col, turnPlayer, pieceType);
applyBoops(this.context, row, col, pieceType);
const graduatedLines = checkGraduation(this.context, turnPlayer);
if (graduatedLines.length > 0) {
processGraduation(this.context, turnPlayer, graduatedLines);
const supply = this.context.value.players[player][pieceType].supply;
if (supply <= 0) {
return `No ${pieceType}s left in ${player}'s supply.`;
}
return null;
}
);
const [player, row, col, type] = playCmd.params as [PlayerType, number, number, PieceType?];
const pieceType = type === 'cat' ? 'cat' : 'kitten';
const winner = checkWinner(this.context);
if (winner) return { winner };
placePiece(this.context, row, col, turnPlayer, pieceType);
applyBoops(this.context, row, col, pieceType);
return { winner: null };
const graduatedLines = checkGraduation(this.context, turnPlayer);
if (graduatedLines.length > 0) {
processGraduation(this.context, turnPlayer, graduatedLines);
}
throw new Error('Too many invalid attempts');
const winner = checkWinner(this.context);
if (winner) return { winner };
return { winner: null };
});
function isValidMove(row: number, col: number): boolean {
+22 -17
View File
@@ -61,28 +61,33 @@ registration.add('setup', async function() {
registration.add('turn <player> <turn:number>', async function(cmd) {
const [turnPlayer, turnNumber] = cmd.params as [PlayerType, number];
const maxRetries = MAX_TURNS * 2;
let retries = 0;
while (retries < maxRetries) {
retries++;
const playCmd = await this.prompt('play <player> <row:number> <col:number>');
const [player, row, col] = playCmd.params as [PlayerType, number, number];
const playCmd = await this.prompt(
'play <player> <row:number> <col:number>',
(command) => {
const [player, row, col] = command.params as [PlayerType, number, number];
if (player !== turnPlayer) continue;
if (!isValidMove(row, col)) continue;
if (isCellOccupied(this.context, row, col)) continue;
if (player !== turnPlayer) {
return `Invalid player: ${player}. Expected ${turnPlayer}.`;
}
if (!isValidMove(row, col)) {
return `Invalid position: (${row}, ${col}). Must be between 0 and ${BOARD_SIZE - 1}.`;
}
if (isCellOccupied(this.context, row, col)) {
return `Cell (${row}, ${col}) is already occupied.`;
}
return null;
}
);
const [player, row, col] = playCmd.params as [PlayerType, number, number];
placePiece(this.context, row, col, turnPlayer);
placePiece(this.context, row, col, turnPlayer);
const winner = checkWinner(this.context);
if (winner) return { winner };
if (turnNumber >= MAX_TURNS) return { winner: 'draw' as WinnerType };
const winner = checkWinner(this.context);
if (winner) return { winner };
if (turnNumber >= MAX_TURNS) return { winner: 'draw' as WinnerType };
return { winner: null };
}
throw new Error('Too many invalid attempts');
return { winner: null };
});
function isValidMove(row: number, col: number): boolean {