Download src/engine.py from algorembrant/CheckerChesser: direct link, hf CLI and curl.
- Browser
- Download file 4.4 kB
-
https://huggingface.co/algorembrant/CheckerChesser/resolve/main/src/engine.py
- Command line
-
hf download hf://algorembrant/CheckerChesser/src/engine.py
-
curl -L -o engine.py https://huggingface.co/algorembrant/CheckerChesser/resolve/main/src/engine.py
4.4 kB
| import chess | |
| import chess.engine | |
| import os | |
| import threading | |
| class EngineHandler: | |
| def __init__(self, engine_path="stockfish.exe"): | |
| self.engine_path = engine_path | |
| self.engine = None | |
| self.lock = threading.Lock() # Prevent concurrent engine access | |
| def initialize_engine(self): | |
| # 1. Check if path exists | |
| if not os.path.exists(self.engine_path): | |
| return False, f"Engine not found at {self.engine_path}. Please place 'stockfish.exe' in the project folder." | |
| # 2. If it is a directory, search for an executable inside | |
| final_path = self.engine_path | |
| if os.path.isdir(self.engine_path): | |
| found_exe = None | |
| for root, dirs, files in os.walk(self.engine_path): | |
| for file in files: | |
| if "stockfish" in file.lower() and file.lower().endswith(".exe"): | |
| found_exe = os.path.join(root, file) | |
| break | |
| if found_exe: | |
| break | |
| if found_exe: | |
| final_path = found_exe | |
| else: | |
| return False, f"Directory found at {self.engine_path}, but no 'stockfish' executable was found inside." | |
| try: | |
| self.engine = chess.engine.SimpleEngine.popen_uci(final_path) | |
| return True, f"Engine initialized successfully ({os.path.basename(final_path)})." | |
| except PermissionError: | |
| return False, f"Permission denied accessing {self.engine_path}. Try running as Administrator or check file properties." | |
| except Exception as e: | |
| return False, f"Failed to initialize engine: {e}" | |
| def get_best_move(self, fen, time_limit=1.0): | |
| if not self.engine: | |
| return None | |
| with self.lock: | |
| try: | |
| board = chess.Board(fen) | |
| result = self.engine.play(board, chess.engine.Limit(time=time_limit)) | |
| return result.move | |
| except Exception as e: | |
| import traceback | |
| traceback.print_exc() | |
| print(f"Error getting best move: {e!r}") | |
| # Try to reinitialize engine if it died | |
| self._try_reinit() | |
| return None | |
| def _try_reinit(self): | |
| """Attempt to reinitialize the engine if it crashed.""" | |
| try: | |
| if self.engine: | |
| try: | |
| self.engine.quit() | |
| except: | |
| pass | |
| self.engine = None | |
| self.initialize_engine() | |
| except: | |
| pass | |
| def get_top_moves(self, fen, limit=3, time_limit=1.0): | |
| if not self.engine: | |
| return [] | |
| with self.lock: | |
| try: | |
| board = chess.Board(fen) | |
| info = self.engine.analyse(board, chess.engine.Limit(time=time_limit), multipv=limit) | |
| if isinstance(info, dict): | |
| info = [info] | |
| top_moves = [] | |
| for i, line in enumerate(info): | |
| if "pv" in line: | |
| move = line["pv"][0] | |
| score = line["score"].relative.score(mate_score=10000) | |
| top_moves.append({ | |
| "rank": i + 1, | |
| "move": move, | |
| "score": score, | |
| "pv": line["pv"] | |
| }) | |
| return top_moves | |
| except Exception as e: | |
| print(f"Error analyzing: {e}") | |
| self._try_reinit() | |
| return [] | |
| def quit(self): | |
| if self.engine: | |
| try: | |
| self.engine.quit() | |
| except: | |
| pass | |
| def get_evaluation(self, fen): | |
| if not self.engine: | |
| return None | |
| with self.lock: | |
| try: | |
| board = chess.Board(fen) | |
| info = self.engine.analyse(board, chess.engine.Limit(depth=15)) | |
| return info["score"].relative.score(mate_score=10000) | |
| except Exception as e: | |
| print(f"Error in evaluation: {e}") | |
| return None | |