feat(server): per-viewer capture tally on joined and update messages
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
import type { CaptureTally, Color } from '@blind-chess/shared';
|
||||
import type { Game } from './state.js';
|
||||
|
||||
/**
|
||||
* Per-viewer capture tally derived from move history. `byYou` is the set of
|
||||
* opponent pieces this viewer has captured; `byOpponent` is the set of this
|
||||
* viewer's pieces the opponent has captured. Pure function of move history —
|
||||
* no live board state, no opponent positions.
|
||||
*/
|
||||
export function captureTally(game: Game, viewer: Color): CaptureTally {
|
||||
const byYou: Record<string, number> = {};
|
||||
const byOpponent: Record<string, number> = {};
|
||||
for (const rec of game.moveHistory) {
|
||||
const captured = rec.capturedPieceType;
|
||||
if (!captured) continue;
|
||||
const bucket = rec.by === viewer ? byYou : byOpponent;
|
||||
bucket[captured] = (bucket[captured] ?? 0) + 1;
|
||||
}
|
||||
return { byYou, byOpponent };
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import { announce } from './translator.js';
|
||||
import { buildView } from './view.js';
|
||||
import { consumeCommitToken } from './ratelimit.js';
|
||||
import { endGame, finalizeIfEnded } from './game-end.js';
|
||||
import { captureTally } from './captures.js';
|
||||
|
||||
async function pokeBot(game: Game): Promise<void> {
|
||||
const driver = getBotDriver(game.id);
|
||||
@@ -147,6 +148,7 @@ async function onHello(ctx: SocketCtx, msg: Extract<ClientMessage, { type: 'hell
|
||||
mode: game.mode,
|
||||
highlightingEnabled: game.highlightingEnabled,
|
||||
opponentConnected: !!game.players[color === 'w' ? 'b' : 'w']?.socket,
|
||||
captures: captureTally(game, color),
|
||||
aiOpponent: game.aiOpponent,
|
||||
});
|
||||
|
||||
@@ -284,6 +286,7 @@ function sendUpdateTo(
|
||||
drawOffer,
|
||||
endReason: game.endReason,
|
||||
winner: game.winner ?? null,
|
||||
captures: captureTally(game, color),
|
||||
aiOpponent: game.aiOpponent,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user