Skip to content

Instantly share code, notes, and snippets.

@ivansglazunov
Created April 19, 2025 10:21
Show Gist options
  • Save ivansglazunov/53a52854c926d5f6b0bfe9387aff502f to your computer and use it in GitHub Desktop.
Save ivansglazunov/53a52854c926d5f6b0bfe9387aff502f to your computer and use it in GitHub Desktop.

Эксперимент по обеспечению FIDE-совместимости Рокировки в Badma

1. Введение: Проблема совместимости с правилами ФИДЕ в chess.js

Изначально мы столкнулись с тем, что используемая библиотека chess.js, хотя и является мощным инструментом для работы с шахматной логикой, не всегда гарантировала стопроцентное следование официальным правилам ФИДЕ. Особенно это касалось сложного механизма рокировки.

Библиотека могла, в некоторых конфигурациях или по умолчанию, допускать рокировку в ситуациях, строго запрещенных правилами ФИДЕ:

  • Рокировка, при которой король начинал движение под шахом.
  • Рокировка, при которой король пересекал поле, находящееся под атакой фигуры противника.
  • Рокировка, при которой король вставал на поле, находящееся под атакой фигуры противника.

Кроме того, стандартные сообщения об ошибках при неудачной рокировке были довольно общими (например, "Invalid move"), что затрудняло отладку и понимание конкретной причины отказа с точки зрения правил ФИДЕ.

Для проекта badma, где важна точность и предсказуемость шахматной логики, такое поведение было неприемлемо. Нам требовалось гарантированное и строгое соблюдение правил ФИДЕ.

2. Наше Решение: Усиление chess.js для строгого соответствия ФИДЕ

Чтобы решить проблему совместимости, мы разработали собственный класс-обертку Chess, расположенный в файле src/chess.ts. Этот класс использует chess.js под капотом, но добавляет необходимый слой валидации и логики для обеспечения строгого соответствия правилам ФИДЕ.

Ключевые изменения и улучшения:

  1. Удаление опции strictFideCastling: Мы убрали эту конфигурационную опцию. Теперь строгие FIDE-проверки для рокировки активны всегда, по умолчанию, без возможности их отключения. Это гарантирует единое и правильное поведение во всем приложении.
  2. Интеграция Валидации в move(): Основной метод для выполнения ходов, move(), теперь включает обязательную и всестороннюю проверку легальности рокировки перед ее выполнением. Если ход идентифицирован как рокировка, он сначала проходит через наш метод isCastlingLegal.
  3. Точная Проверка Условий ФИДЕ: Мы реализовали (или уточнили существующую) логику для точной проверки каждого аспекта правил рокировки ФИДЕ:
    • isKingInCheck(side): Определяет, находится ли король указанной стороны под шахом. Рокировка невозможна, если король под шахом.
    • hasCastlingRights(side, kingside): Проверяет наличие соответствующих прав на рокировку (K, Q, k, q) в текущей FEN-строке. Права теряются при движении короля или соответствующей ладьи.
    • isCastlingPathClear(kingside, side): Проверяет, что все поля между королем и ладьей (исключая их самих) пусты. Для O-O это f1/g1 или f8/g8, для O-O-O это b1/c1/d1 или b8/c8/d8.
    • isCastlingPathSafe(kingside, side): Проверяет, что ни одно из полей, на которых король находится в начале хода, проходит через которое, и на котором оказывается в конце хода, не атаковано фигурами противника. Для O-O это e1/f1/g1 или e8/f8/g8. Для O-O-O это e1/d1/c1 или e8/d8/c8.
  4. Конкретные Сообщения об Ошибках: Вместо общего "Invalid move", наш метод move() теперь возвращает точную причину, почему рокировка невозможна согласно правилам ФИДЕ (например, "Castling not allowed: King is in check", "Castling not allowed: Path not clear" и т.д.). Это значительно упрощает отладку и тестирование.

Таким образом, класс Chess надстраивает базовую функциональность chess.js, обеспечивая строгую валидацию рокировки по ФИДЕ и предоставляя более информативную обратную связь.

3. Подробный Разбор Тестовых Сценариев Рокировки (chess-js.fide-castling.test.ts)

Цель этого набора тестов — досконально проверить каждый аспект правил рокировки ФИДЕ в нашей реализации Chess. Мы использовали подход "чистой доски" (r3k2r/8/8/8/8/8/8/R3K2R w KQkq), расставляя нужные фигуры с помощью chess.put() и chess.remove(), чтобы изолировать и точно проверить каждый сценарий.

А. Обнаружение Хода Рокировки (Castling Move Detection)

  • Цель: Убедиться, что метод isCastlingMove правильно распознает специальные ходы короля на две клетки как рокировку.
  • Проверено:
    • e1->g1 (Белые O-O) - Распознается как рокировка.
    • e1->c1 (Белые O-O-O) - Распознается как рокировка.
    • e8->g8 (Черные O-O) - Распознается как рокировка.
    • e8->c8 (Черные O-O-O) - Распознается как рокировка.
    • Обычные ходы короля (e1->f1, e1->d1) - Не распознаются как рокировка.
    • Ходы других фигур - Не распознаются как рокировка.
  • Результат: Все тесты пройдены успешно. ✅

Б. Чистота Пути (Castling Path Clearance)

  • Цель: Проверить метод isCastlingPathClear.
  • Проверено:
    • O-O (Белые): Путь f1/g1 чист -> true. Путь заблокирован фигурой на g1 -> false.
    • O-O-O (Белые): Путь b1/c1/d1 чист -> true. Путь заблокирован фигурой на b1 -> false.
    • (Аналогичные проверки для черных подразумеваются симметрией).
  • Результат: Все тесты пройдены успешно. ✅

В. Безопасность Пути (Castling Path Safety)

  • Цель: Проверить метод isCastlingPathSafe. Это самая критичная часть для ФИДЕ-совместимости. Король не может начинать, проходить через или оказываться на атакованном поле.
  • Проверено (для белых, черные симметрично):
    • Безопасный путь (O-O и O-O-O): На чистой доске без атакующих черных фигур пути e1/f1/g1 и e1/d1/c1 безопасны -> true.
    • Небезопасный путь f1 (O-O):
      • Атака на f1 заблокирована белой пешкой f2 -> isSquareAttacked('f1') -> false, isCastlingPathSafe(O-O) -> true.
      • Атака на f1 реальна (чистый путь) -> isSquareAttacked('f1') -> true, isCastlingPathSafe(O-O) -> false.
    • Небезопасный путь g1 (O-O):
      • Атака на g1 заблокирована белой пешкой g2 -> isSquareAttacked('g1') -> false, isCastlingPathSafe(O-O) -> true.
      • Атака на g1 реальна (чистый путь) -> isSquareAttacked('g1') -> true, isCastlingPathSafe(O-O) -> false.
    • Небезопасный путь d1 (O-O-O):
      • Атака на d1 заблокирована белой пешкой d2 -> isSquareAttacked('d1') -> false, isCastlingPathSafe(O-O-O) -> true.
      • Атака на d1 реальна (чистый путь) -> isSquareAttacked('d1') -> true, isCastlingPathSafe(O-O-O) -> false.
    • Небезопасный путь c1 (O-O-O):
      • Атака на c1 заблокирована белой пешкой c2 -> isSquareAttacked('c1') -> false, isCastlingPathSafe(O-O-O) -> true.
      • Атака на c1 реальна (чистый путь) -> isSquareAttacked('c1') -> true, isCastlingPathSafe(O-O-O) -> false.
  • Результат: Все тесты пройдены успешно после рефакторинга FEN и использования put(). ✅

Г. Обнаружение Атаки на Поле (Square Attack Detection)

  • Цель: Убедиться в корректности isSquareAttacked, так как от нее зависит isCastlingPathSafe.
  • Проверено: Базовые атаки всех фигур (пешка, конь, король, слон, ладья), включая ситуации с блокировкой пути.
  • Результат: Все тесты пройдены успешно. ✅

Д. Обнаружение Шаха Королю (King Check Detection)

  • Цель: Убедиться в корректности isKingInCheck. Рокировка под шахом запрещена.
  • Проверено:
    • Шах от разных фигур (ферзь, слон, ладья, пешка).
    • Отсутствие шаха, если путь атаки заблокирован.
    • Сценарий с постановкой и удалением атакующей фигуры (chess.put и chess.remove).
  • Результат: Все тесты пройдены успешно после исправления логики одного из тестов. ✅

Е. Комплексная Легальность Рокировки (Comprehensive Castling Legality)

  • Цель: Проверить метод isCastlingLegal, который объединяет все правила ФИДЕ.
  • Проверено:
    • Все условия выполнены -> legal: true.
    • Король под шахом -> legal: false, reason: 'King is in check'.
    • Путь не чист (фигура мешает) -> legal: false, reason: 'Path not clear'.
    • Путь не безопасен (атаковано поле e1/f1/g1 или e1/d1/c1) -> legal: false, reason: 'King passes through or lands on attacked square'.
    • Нет прав на рокировку (в FEN) -> legal: false, reason: 'No castling rights'.
  • Результат: Все тесты пройдены успешно после рефакторинга FEN. ✅

Ж. Удобные Методы (Combined Castling Convenience Methods)

  • Цель: Проверить методы canCastleKingside и canCastleQueenside.
  • Проверено: Комбинации различных условий (все легально, король под шахом, путь блокирован, путь не безопасен) для обеих сторон и обоих флангов.
  • Результат: Все тесты пройдены успешно после исправления логики одного из сценариев (атакующая фигура ставилась не на то поле). ✅

4. Заключение

Проведенная работа по созданию класса-обертки Chess и тщательному тестированию всех аспектов рокировки позволила нам добиться полного соответствия правилам ФИДЕ в нашей реализации. Удаление опциональных строгих проверок и внедрение обязательной валидации в метод move гарантирует предсказуемое и корректное поведение шахматного движка во всех сценариях, связанных с рокировкой. Это значительно повышает надежность системы и упрощает дальнейшую разработку и тестирование. Мы успешно "научили" наш шахматный модуль строгим правилам ФИДЕ! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment