Загрузка данных


import chess
import chess.engine

class ChessEngine:
    def __init__(self, engine_path="stockfish.exe", time_limit=0.1):
        self.engine_path = engine_path
        self.time_limit = time_limit
        self.engine = None
        self.enabled = False  # Отключен по умолчанию
        self._start_engine()

    def _start_engine(self):
        """Запуск или перезапуск процесса Stockfish."""
        # Если старый процесс еще существует — закрываем его
        if self.engine:
            try:
                self.engine.quit()
            except Exception:
                pass
            self.engine = None

        try:
            # Ищем Stockfish в папке Windows или текущей директории
            path_to_use = self.engine_path
            
            self.engine = chess.engine.SimpleEngine.popen_uci(path_to_use)
            
            options = {
                "Hash": 16,
                "Threads": 1
            }
            for key, value in options.items():
                if key in self.engine.options:
                    self.engine.configure({key: value})
                    
            print("[ОК] Движок Stockfish готов!")
        except Exception as e:
            print(f"[ПРЕДУПРЕЖДЕНИЕ] Не удалось запустить движок: {e}")
            self.engine = None

    def toggle(self):
        """Переключает активное состояние движка."""
        self.enabled = not self.enabled
        # При включении проверяем, жив ли процесс
        if self.enabled and (not self.engine or self.engine.is_terminated()):
            self._start_engine()
        return self.enabled

    def analyze_fen(self, fen):
        if not self.enabled:
            return None, "Движок отключен [Жми S]"

        # Если процесс Stockfish упал — перезапускаем его прямо на лету!
        if not self.engine or self.engine.is_terminated():
            self._start_engine()
            if not self.engine:
                return None, "Ошибка: Stockfish не запущен"

        try:
            board = chess.Board(fen)
            
            # Проверка корректности FEN позиции перед отправкой
            if not board.is_valid():
                return None, "Некорректная позиция FEN"

            result = self.engine.analyse(board, chess.engine.Limit(time=self.time_limit))
            
            best_move = result.get("pv")[0] if "pv" in result and result["pv"] else None
            score = result.get("score")

            if score is not None:
                if score.is_mate():
                    eval_str = f"Мат в {score.relative.mate()}"
                else:
                    cp = score.relative.score() / 100.0
                    eval_str = f"{'+' if cp > 0 else ''}{cp:.2f}"
            else:
                eval_str = "0.00"

            return best_move.uci() if best_move else None, eval_str

        except chess.engine.EngineTerminatedError:
            print("[ОШИБКА] Stockfish аварийно завершился! Перезапуск...")
            self._start_engine()
            return None, "Перезапуск Stockfish..."
        except Exception as e:
            return None, f"Ошибка анализа: {e}"

    def close(self):
        if self.engine:
            try:
                self.engine.quit()
            except Exception:
                pass