Голосовой шахматный навык для Яндекс.Алисы: игра в шахматы вслепую с озвучиванием ходов.
- Голосовая игра в шахматы через Яндекс.Алису
- Шахматный движок Stockfish (локальный бинарь, запускается по UCI через
python-chess) - Распознавание ходов в нескольких форматах: SAN, длинная нотация (
e2e4), русскоязычные команды («пешка е4», «конь на эф 3») - Превращение пешки (с явным указанием фигуры или ферзём по умолчанию)
- Специальные команды и интенты: помощь, новая игра, сдача, ничья, отмена хода, показать доску, выбор уровня сложности
- Восстановление состояния игры между запросами через
user_state_update - Идемпотентность повторных запросов по
message_id - Поддержка
YANDEX.REPEATчерезsession_state - Версионируемая схема состояния игры (Pydantic V2) с graceful fallback при ошибках десериализации
Перечислены в skill_state.py:
INITIATED— приветствие, ожидание согласия на игруWAITING_CONFIRM— ожидание подтверждения начала игрыWAITING_COLOR— выбор цвета пользователемWAITING_SKILL_LEVEL— выбор уровня сложностиWAITING_MOVE— ожидание хода пользователяWAITING_DRAW_CONFIRM— подтверждение предложения ничьейWAITING_RESIGN_CONFIRM— подтверждение сдачиWAITING_NEWGAME_CONFIRM— подтверждение начала новой партииGAME_OVER— партия завершена
Полная диаграмма переходов: docs/diagrams/state_diagram.md.
Доступны в большинстве состояний игры:
- «Помощь» — справка по игре
- «Покажи доску» — текущая позиция в виде FEN/Unicode
- «Новая игра» — начать новую партию
- «Уровень сложности» — изменить уровень игры
- «Повтори» — повтор последнего ответа Алисы (
YANDEX.REPEAT) - «Отмени ход» / «Назад» — откатить последний ход (если доступно)
- «Ничья» — предложить ничью
- «Сдаюсь» — сдаться
-
Клонируйте репозиторий:
git clone https://github.com/axtrace/alisa_chess.git cd alisa_chess -
Создайте и активируйте виртуальное окружение:
python3 -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate
-
Установите Python-зависимости:
pip install -r requirements.txt
-
Положите бинарь Stockfish в корень проекта рядом с
alice_chess.pyпод именемstockfish(исполняемый файл):chmod +x ./stockfish
Бинарь не входит в репозиторий, его нужно скачать или собрать самостоятельно с официального сайта.
alice_chess.py— основной классAliceChess, точка входа в обработку запросаalice_serverless.py— точка входа для Yandex Cloud Functions (handler(event, context))game.py— игровая логика, обёртка надchess.Boardи UCI-движком Stockfishgame_state.py— Pydantic-схемыGameStateV1/GameStateV2, миграции и сериализацияskill_state.py— enum состояний навыкаhandlers/— обработчики состояний (WaitingMoveHandler,InitiatedHandler,BaseConfirmationHandlerи т. д.)request_validators/— валидаторы интентовmove_extractor.py— парсинг хода пользователя из интентов и текста (включая кириллицу)speaker.py,text_preparer.py— построение текста и TTS-ответаtexts.py— шаблоны фразintents/— YAML-описания интентов Алисыtests/— юнит-тесты (pytest/unittest)docs/— архитектурная документация и диаграммы
Алиса: Давайте сыграем в шахматы.
Юзер: Да.
Алиса: За какую сторону играем — белые или чёрные?
Юзер: Белые.
Алиса: Хорошо. Ваш ход.
Юзер: e2 e4.
Алиса: Конь f6. Ваш ход.
Юзер: Покажи доску.
Алиса: [показывает текущую позицию]
...
Алиса: Мат. Спасибо за игру.
Состояние игры передаётся через state.user.game_state и обновляется через user_state_update. Схема описана в game_state.py (GameStateV2):
{
"request": {"command": "e2e4", "...": "..."},
"state": {
"user": {
"game_state": {
"_version": 2,
"board_state": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
"skill_state": "WAITING_MOVE",
"prev_skill_state": "WAITING_CONFIRM",
"user_color": "WHITE",
"comp_color": "BLACK",
"skill_level": 1,
"time_level": 0.1
}
},
"session": {
"last_message_id": 3,
"previous_response": {"text": "...", "tts": "...", "end_session": false}
}
}
}board_state— FEN текущей позиции.skill_state/prev_skill_state— текущее и предыдущее состояния навыка (значения изSkillState)._version— версия схемы; при чтении состояний с другой схемой выполняется автоматическая миграция (см.GameState.from_dict).session_state.last_message_id— используется для идемпотентности (повторныйmessage_idвозвращает предыдущий ответ).session_state.previous_response— последний ответ, возвращается приYANDEX.REPEAT.
Запуск всех тестов:
python3 -m pytest tests/ -vИли через unittest:
python3 -m unittest discover testsПоддерживается развёртывание как Yandex Cloud Function. Точка входа — alice_serverless.handler. Workflow для деплоя лежат в .github/workflows/. Подробнее в docs/deployment.md.
Изменения после одобрения модератора:
Удалены процессы Manual Deploy to TESTING YaCloud Functions и Manual Deploy to PROD YaCloud Functions, остались только Manual Deploy 2 PROD YaCloud Functions и Auto Deploy 2 TESTING YaCloud Functions. Переменные оставлены с постфиксом _2 для совместимости.
- Основная логика — класс
AliceChess; обрабатывает запрос как контекстный менеджер, гарантированно закрывая UCI-движок. - Игровая обёртка — класс
Gameс ленивой инициализацией Stockfish и обязательнымengine.quit()через__exit__. - Маршрутизация по состояниям реализована в
AliceChess.handle_requestна основеSkillState. - Каждое состояние обрабатывается соответствующим хендлером из
handlers/, наследующимBaseHandler. - Специальные команды (помощь, показ доски, повтор, новая игра и т. д.) обрабатываются в
SpecialIntentHandlerнезависимо от текущего состояния. - Обработка ошибок двухуровневая:
BaseHandler.safe_handleвозвращает дружелюбное сообщение, аalice_serverless.handlerловит катастрофические исключения и не теряетuser_state_update.
Подробности: docs/architecture.md, диаграммы состояний и последовательности в docs/diagrams/.
Два крупных проекта для оптимизации производительности:
- Кэш позиций в Redis (ADR-0004) — ускорение повторных позиций в 50–100x раз
- Stockfish микросервис (ADR-0005) — исключение холодного старта, persistent engine с fallback
Полный roadmap с графиком и задачами: docs/ROADMAP.md.
- Шахматный движок: Stockfish, локальный бинарь, UCI-протокол через python-chess.
- Валидация состояния: Pydantic v2 (
requirements.txt). - Сервер исторически использовал отдельный HTTP-API (axtrace/chessapi) — в текущей версии Stockfish запускается локально внутри функции.
PR приветствуются. Перед отправкой — прогоните тесты и убедитесь, что pytest зелёный.
MIT License © 2024 axtrace