Spaces:
Sleeping
Sleeping
File size: 2,194 Bytes
06e83d9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# ======================================================
# 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")
@tool(args_schema=ChessInput)
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}" |