4407110147
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>
21 lines
970 B
TypeScript
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);
|
|
}
|