/** * 井字棋游戏状态扩展 */ /** * 玩家类型 */ export type Player = 'X' | 'O'; /** * 单元格状态 */ export interface CellState { /** 单元格 ID(如 A1, B2, C3) */ id: string; /** 行索引 (0-2) */ row: number; /** 列索引 (0-2) */ col: number; /** 当前玩家标记,null 表示空 */ player: Player | null; } /** * 井字棋游戏元数据 */ export interface TicTacToeMetadata { /** 当前玩家 */ currentPlayer: Player; /** 游戏是否结束 */ gameEnded: boolean; /** 获胜者,null 表示平局或未结束 */ winner: Player | null; /** 获胜的组合(如果有) */ winningCombination?: string[]; /** 游戏历史 */ moveHistory: MoveRecord[]; /** 总回合数 */ totalMoves: number; } /** * 移动记录 */ export interface MoveRecord { /** 移动的玩家 */ player: Player; /** 移动的单元格 ID */ cellId: string; /** 移动时间戳 */ timestamp: number; } /** * 获胜组合类型 */ export type WinningLine = | { type: 'row'; index: number } | { type: 'column'; index: number } | { type: 'diagonal'; direction: 'main' | 'anti' }; /** * 井字棋棋盘配置 */ export interface TicTacToeBoardConfig { /** 棋盘大小(默认 3x3) */ size: number; /** 单元格 ID 前缀 */ cellIdPrefix: string; } /** * 默认的 3x3 棋盘配置 */ export const DEFAULT_BOARD_CONFIG: TicTacToeBoardConfig = { size: 3, cellIdPrefix: 'cell', }; /** * 获取单元格 ID */ export function getCellId(row: number, col: number, prefix: string = 'cell'): string { const rowLabel = String.fromCharCode('A'.charCodeAt(0) + row); return `${prefix}-${rowLabel}${col + 1}`; } /** * 解析单元格 ID */ export function parseCellId(cellId: string): { row: number; col: number } | null { const match = cellId.match(/^cell-([A-Z])(\d+)$/); if (!match) return null; return { row: match[1].charCodeAt(0) - 'A'.charCodeAt(0), col: parseInt(match[2], 10) - 1, }; } /** * 检查是否是有效的单元格 ID */ export function isValidCellId(cellId: string, size: number = 3): boolean { const parsed = parseCellId(cellId); if (!parsed) return false; return parsed.row >= 0 && parsed.row < size && parsed.col >= 0 && parsed.col < size; } /** * 生成所有单元格 ID */ export function getAllCellIds(size: number = 3, prefix: string = 'cell'): string[] { const cells: string[] = []; for (let row = 0; row < size; row++) { for (let col = 0; col < size; col++) { cells.push(getCellId(row, col, prefix)); } } return cells; } /** * 获取所有可能的获胜组合 */ export function getWinningCombinations(size: number = 3): string[][] { const combinations: string[][] = []; // 行 for (let row = 0; row < size; row++) { const rowCells: string[] = []; for (let col = 0; col < size; col++) { rowCells.push(getCellId(row, col)); } combinations.push(rowCells); } // 列 for (let col = 0; col < size; col++) { const colCells: string[] = []; for (let row = 0; row < size; row++) { colCells.push(getCellId(row, col)); } combinations.push(colCells); } // 主对角线 const mainDiagonal: string[] = []; for (let i = 0; i < size; i++) { mainDiagonal.push(getCellId(i, i)); } combinations.push(mainDiagonal); // 反对角线 const antiDiagonal: string[] = []; for (let i = 0; i < size; i++) { antiDiagonal.push(getCellId(i, size - 1 - i)); } combinations.push(antiDiagonal); return combinations; }