gaia-final-assignment / tools /image_chess.py
ykumar2020's picture
Publish verified modular GAIA agent source
c641d5f verified
Raw
History Blame Contribute Delete
1.65 kB
"""Deterministic chess calculations after a board has been transcribed to FEN."""
from __future__ import annotations
import shutil
def resolve_stockfish(stockfish_path: str | None = None) -> str:
"""Resolve Stockfish or fail closed so the model never guesses a move."""
resolved = stockfish_path or shutil.which("stockfish")
if not resolved:
raise RuntimeError(
"Stockfish is required for chess answers. Set STOCKFISH_PATH or install stockfish."
)
return resolved
def best_move_san(fen: str, stockfish_path: str | None = None, depth: int = 18) -> str:
import chess
import chess.engine
board = chess.Board(fen)
with chess.engine.SimpleEngine.popen_uci(
resolve_stockfish(stockfish_path)
) as engine:
move = engine.play(board, chess.engine.Limit(depth=depth)).move
return board.san(move)
def analyze_chess_fen(
fen: str, stockfish_path: str | None = None, depth: int = 18
) -> str:
"""Return legal checks/mates and an optional engine best move in SAN."""
import chess
board = chess.Board(fen)
checks: list[str] = []
mates: list[str] = []
for move in board.legal_moves:
san = board.san(move)
board.push(move)
if board.is_checkmate():
mates.append(san)
elif board.is_check():
checks.append(san)
board.pop()
best = None
if stockfish_path or shutil.which("stockfish"):
best = best_move_san(fen, stockfish_path, depth)
return f"FEN: {fen}\nLegal moves: {board.legal_moves.count()}\nChecks: {checks}\nMates in one: {mates}\nEngine best SAN: {best}"