Spaces:
Sleeping
Sleeping
# ====================================================== | |
# ChessPositionSolverTool | |
# • Uses chessvision.ai’s open-source detector to turn a board image into FEN | |
# • Feeds that FEN to Stockfish (via python-chess) and returns best move in | |
# short algebraic notation (e.g. “Qh5#”) | |
# • Requires: | |
# pip install chessvision python-chess opencv-python | |
# and Stockfish binary in PATH (adjust `STOCKFISH_PATH` if needed) | |
# ====================================================== | |
import requests, cv2, numpy as np, os, subprocess, json, tempfile | |
from pydantic import BaseModel, Field | |
from langchain_core.tools import tool | |
import chess, chess.engine | |
from chesscog import Chesscog # <- pip install chesscog | |
STOCKFISH_PATH = os.getenv("STOCKFISH_PATH", "stockfish") # apt-get install stockfish | |
class ChessInput(BaseModel): | |
image_url: str = Field(..., description="PNG/JPG of the chess position") | |
stockfish_depth: int = Field(18, ge=10, le=30, | |
description="Search depth for Stockfish") | |
def chess_position_solver(image_url: str, stockfish_depth: int = 18) -> str: | |
""" | |
Converts a chessboard image to FEN with chesscog, sends it to Stockfish, | |
and returns the best move in algebraic notation (e.g. 'Rxf2+'). | |
""" | |
try: | |
# 1 - download image | |
img_bytes = requests.get(image_url, timeout=30).content | |
img = cv2.imdecode(np.frombuffer(img_bytes, np.uint8), cv2.IMREAD_COLOR) | |
# 2 - infer FEN with chesscog | |
detector = Chesscog(device="cpu") # auto-downloads model weights | |
fen = detector.get_fen(img) | |
if fen is None: | |
return "chess_position_solver failed: board not recognised." | |
board = chess.Board(fen) | |
# 3 - Stockfish | |
engine = chess.engine.SimpleEngine.popen_uci(STOCKFISH_PATH) | |
result = engine.play(board, chess.engine.Limit(depth=stockfish_depth)) | |
engine.quit() | |
best_move_san = board.san(result.move) # algebraic, e.g. 'Qh5#' | |
return best_move_san | |
except Exception as e: | |
return f"chess_position_solver failed: {e}" |