Files
blind_chess/packages/server/src/game-end.ts
T
claude (blind_chess) 4407110147 fix(bot): finalize game on bot checkmate; harden driver dispatch
Extract endGame/finalizeIfEnded to game-end.ts so driver.ts can call
finalizeIfEnded after an applied move (fix: bot checkmate was not
setting game.status='finished'). Wrap entire dispatch() call in
try/catch for exception safety. Move lastSeenAnnouncementCount advance
to after successful dispatch so retry attempts see FSM rejection
announcements. Add checkmate-finalize test; lock retry-cap at 5 calls.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 14:04:22 -04:00

21 lines
970 B
TypeScript

import type { Color } from '@blind-chess/shared';
import type { Game } from './state.js';
export function endGame(game: Game, reason: Game['endReason'], winner: Color | null): void {
game.status = 'finished';
game.endReason = reason;
game.winner = winner;
game.finishedAt = Date.now();
}
export function finalizeIfEnded(game: Game, announcements: ReadonlyArray<{ text: string }>): void {
// Detect terminal moderator announcements.
const lastTexts = new Set(announcements.map((a) => a.text));
if (lastTexts.has('white_checkmate')) endGame(game, 'checkmate', 'w');
else if (lastTexts.has('black_checkmate')) endGame(game, 'checkmate', 'b');
else if (lastTexts.has('stalemate')) endGame(game, 'stalemate', null);
else if (lastTexts.has('draw_insufficient')) endGame(game, 'insufficient', null);
else if (lastTexts.has('draw_threefold')) endGame(game, 'threefold', null);
else if (lastTexts.has('draw_fifty')) endGame(game, 'fifty_move', null);
}