Spaces:
Sleeping
Sleeping
import { Chess, Square, Color } from 'chess.js' | |
import { GameResult, GameTermination } from '../types/chess' | |
export function evaluateGameState(chess: Chess): GameResult { | |
const isGameOver = chess.isGameOver() | |
if (!isGameOver) { | |
return { | |
isGameOver: false, | |
winner: null, | |
message: '', | |
terminationReason: '' | |
} | |
} | |
if (chess.isCheckmate()) { | |
const winner = chess.turn() === 'w' ? 'b' : 'w' | |
return { | |
isGameOver: true, | |
winner, | |
message: `Checkmate! ${winner === 'w' ? 'White' : 'Black'} wins!`, | |
terminationReason: GameTermination.CHECKMATE, | |
details: `${winner === 'w' ? 'White' : 'Black'} delivered checkmate` | |
} | |
} | |
if (chess.isStalemate()) { | |
return { | |
isGameOver: true, | |
winner: null, | |
message: 'Game drawn by stalemate!', | |
terminationReason: GameTermination.STALEMATE, | |
details: 'No legal moves available but king is not in check' | |
} | |
} | |
if (chess.isInsufficientMaterial()) { | |
return { | |
isGameOver: true, | |
winner: null, | |
message: 'Game drawn by insufficient material!', | |
terminationReason: GameTermination.INSUFFICIENT_MATERIAL, | |
details: 'Neither side has enough material to checkmate' | |
} | |
} | |
if (chess.isThreefoldRepetition()) { | |
return { | |
isGameOver: true, | |
winner: null, | |
message: 'Game drawn by threefold repetition!', | |
terminationReason: GameTermination.THREEFOLD_REPETITION, | |
details: 'The same position occurred three times' | |
} | |
} | |
if (chess.isDraw()) { | |
return { | |
isGameOver: true, | |
winner: null, | |
message: 'Game drawn!', | |
terminationReason: GameTermination.FIFTY_MOVE_RULE, | |
details: 'Draw by 50-move rule or other draw condition' | |
} | |
} | |
return { | |
isGameOver: true, | |
winner: null, | |
message: 'Game ended', | |
terminationReason: 'unknown' | |
} | |
} | |
export function isPotentialPromotion(chess: Chess, from: Square, to: Square): boolean { | |
const piece = chess.get(from) | |
if (!piece || piece.type !== 'p') return false | |
const toRank = parseInt(to[1]) | |
return (piece.color === 'w' && toRank === 8) || (piece.color === 'b' && toRank === 1) | |
} | |
export function isSquareLight(square: Square): boolean { | |
const file = square.charCodeAt(0) - 97 | |
const rank = parseInt(square[1]) - 1 | |
return (file + rank) % 2 === 0 | |
} | |
export function formatMoveTime(timestamp: Date): string { | |
return timestamp.toLocaleTimeString([], { | |
hour: '2-digit', | |
minute: '2-digit', | |
second: '2-digit' | |
}) | |
} |