Files
blind_chess/packages/server/src/state.ts
T
2026-04-28 14:07:01 -04:00

61 lines
1.4 KiB
TypeScript

import type { Chess } from 'chess.js';
import type { WebSocket } from 'ws';
import type {
Announcement,
Color,
EndReason,
GameId,
GameStatus,
Mode,
PieceType,
PlayerToken,
PromotionType,
Square,
} from '@blind-chess/shared';
export interface MoveRecord {
ply: number;
by: Color;
from: Square;
to: Square;
san: string;
capturedPieceType?: PieceType;
promotion?: PromotionType;
flags: { castle?: 'k' | 'q'; enPassant?: boolean; check?: boolean; mate?: boolean };
at: number;
}
export interface PlayerSlot {
token: PlayerToken;
socket: WebSocket | null;
joinedAt: number;
rateBucket: { tokens: number; last: number };
}
export interface Game {
id: GameId;
mode: Mode;
highlightingEnabled: boolean;
status: GameStatus;
createdAt: number;
finishedAt?: number;
endReason?: EndReason;
winner?: Color | null;
chess: Chess;
moveHistory: MoveRecord[];
announcements: Announcement[];
players: { w: PlayerSlot | null; b: PlayerSlot | null };
armed: { color: Color; from: Square } | null;
drawOffer: { from: Color; at: number } | null;
disconnectAt: { w?: number; b?: number };
lastBroadcastIdx: { w: number; b: number };
aiOpponent?: { color: Color; brain: 'casual' | 'recon' };
}
export const RATE_LIMIT = { capacity: 20, refillPerSec: 10 };
export const GRACE_MS = 5 * 60 * 1000;
export const PRUNE_AFTER_FINISHED_MS = 30 * 60 * 1000;