851: Пакет/Покерный Движок
- Интегрируется с:
- Визуализируется с помощью:
Строгая, не зависящая от конкретной игры архитектура, реализующая правила Покера (Техасский Холдем и т.д.). Он служит ядром логики для экосистемы, используя протокольный дизайн (State, Game, Command) для отделения сложной покерной механики от среды выполнения.
Покерный Движок (@idealic/poker-engine) — это набор инструментов для управления покерными играми. Он создаёт абстрактную сущность из специализированных утилит, которые позволяют создавать, развивать и завершать игры. Хотя он сфокусирован на покере, его архитектурные паттерны применимы к любой пошаговой игре.
Надёжность
Движок разработан с использованием строгого подхода, основанного на спецификациях, что гарантирует формальное определение каждого правила и механики. Он подкреплён примерно 3000 тестами, охватывающими широкий спектр сценариев — от стандартной игры до сложных крайних случаев, таких как многосторонние побочные банки и разделённые банки, что гарантирует абсолютную стабильность и корректность.
Кроме того:
- Фаззинг-тестирование: Полный жизненный цикл игры непрерывно проверяется с помощью фаззинг-тестирования на уровне интеграции с Игровым Сервисом, симулируя хаотичные условия реального мира.
- Проверенное наследие: Логика движка основана на системе, совместимой с форматом раздач PokerStars, которая прошла стресс-тестирование на наборе данных из более чем 10 миллионов исторических игр.
Принципы Дизайна
Движок построен на шести основных инвариантах:
- Неизменяемость: Все изменения состояния создают новые объекты (глубокое копирование), что гарантирует сохранение истории.
- Детерминизм: Использование генератора случайных чисел с начальным значением (seed) гарантирует точное воспроизведение игр.
- Сначала проверка: Действия проверяются перед применением, чтобы предотвратить повреждение состояния.
- Разделение ответственности: Чёткие границы между Данными (
State), средой выполнения (Game) и логикой (Processors). - На основе действий: Система, основанная на событиях, где все изменения проходят через стандартизированные строки действий.
- На основе протоколов: Универсальные пространства имён создают единый уровень API.
Паттерн Абстракции Пространства Имён
Движок реализует протокольный дизайн через четыре основных пространства имён, которые действуют как универсальные обёртки.
1. Пространство имён State (Функциональное ядро)
Poker.State (ранее Hand) — это универсальный протокол нотации игры.
- Универсальная нотация: Представляет ЛЮБОЕ состояние пошаговой игры (Покер, Шахматы и т.д.) в виде последовательности действий.
- Источник истины: Содержит полную историю, необходимую для восстановления игры.
- Функциональное ядро: Чистая, неизменяемая структура данных, изменяемая только через чистые функции-редьюсеры.
- Перспективы: Поддерживает
personalize()для создания маскированных представлений для конкретных игроков (скрывая карманные карты).
2. Пространство имён Game (Среда выполнения)
Poker.Game — это протокол состояния времени выполнения (императивная оболочка).
- Живое состояние: Преобразует статическую нотацию
Stateв изменяемый, запрашиваемый объект времени выполнения. - Обеспечение правил: Обрабатывает все правила игры, проверку (
canApplyAction) и развитие игры. - Швейцарский нож: Предоставляет утилиты для управления временем, индексации игроков и анализа состояния.
- Развитие: Метод
applyAction(game, action)является основным драйвером движка, изменяя состояние игры на основе входных данных.
3. Пространство имён Command (Интерфейс)
Poker.Command — это протокол генерации действий.
- Слой трансляции: Преобразует высокоуровневые намерения пользователя (клики в интерфейсе) в стандартизированные строки Действий.
- Осведомлённость о состоянии: Считывает текущий
Gameдля генерации допустимых действий (например, вычисление правильной суммы для командыallIn). - Разделение: Отделяет взаимодействия с пользовательским интерфейсом от основной обработки движка.
4. Пространство имён Format (Сериализатор)
Poker.Format предоставляет специализированные утилиты для обработки данных.
- Сериализация/Десериализация: Эффективное кодирование и декодирование состояний игры и действий для передачи по сети или хранения.
- Парсинг истории раздач: Преобразование необработанного текста истории раздач в структурированные объекты
State, совместимые с основными форматами, такими как PokerStars.
Статистика и Аналитика
Движок включает в себя выделенное пространство имён Poker.Stats для глубокой аналитики.
- Философия: Различает статистику (сырые счётчики, отслеживаемые в реальном времени, например,
three_bet_attempts) и метрики (производные вычисления, например,three_bet_frequency). - Позиционное отслеживание: Отслеживает маневры с явным позиционным контекстом (в позиции/без позиции), например,
cbet_ip_attemptsпротивcbet_oop_attempts. - Агрегация: Поддерживает агрегацию данных по игроку, улице торгов или месту для отчётности.
Архитектура Системы
Ответственность Клиента и Сервера
Покерный Движок работает как на клиенте, так и на сервере.
- На стороне клиента: Обрабатывает оптимистичный рендеринг и позволяет пользователю выполнять действия на основе локального состояния.
- На стороне сервера: Выступает в качестве конечного авторитета для проверки действий, очистки игры и случайности.
Интеграция
- Бэкенд: @idealic/game-service — Управляет сессиями, сохранением данных и сетевым взаимодействием.
- Фронтенд: @idealic/poker-ui — Отображает состояние
Game.
Жизненный Цикл Игры
Покерный Движок работает как конвейер «запрос-ответ».
- Присоединение и инициализация: Игроки запрашивают присоединение; система находит/создаёт стол; ожидает 2+ активных игроков.
- Создание игры: Авторитетное Состояние создаётся с безопасным начальным значением; происходит начальная раздача; состояние сохраняется и рассылается.
- Цикл действий игрока: Клиент отправляет действие -> Движок обрабатывает -> Новое состояние сохраняется/очищается/рассылается.
- Завершение и преемственность: Раздача заканчивается; движок перемещает баттон, обрабатывает блайнды, готовит следующую раздачу.
- Управление жизненным циклом игрока: Запросы на выход/паузу/возобновление ставятся в очередь на следующую игру.
- Состояние ожидания: Приостанавливается, если активных игроков < 2.
- Обработка тайм-аутов: Периодические проверки применяют действия по умолчанию, чтобы игра продолжалась.
Основные Возможности
- Управление состоянием: Детерминированная раздача, отслеживание сложного состояния ставок и управление побочными банками.
- Обеспечение правил: Строгая проверка правил ставок, продвижения по улицам торгов и логики вскрытия карт.
- Управление игроками: Отслеживает позиции (Баттон, МБ, ББ), стеки и историю действий.
- Игровой процесс:
- Крупье: Координирует поток между действиями дилера и игрока.
- Дилер: Автономный агент, который обрабатывает автоматическое развитие игры (раздача карт, переход по улицам).
- Вскрытие карт: Быстрая оценка силы комбинаций на основе таблиц поиска (
utils/hand-strength.ts) для определения победителя.
Формат Действий
Движок использует стандартизированный строковый формат для всех событий:
- Игрок:
'p1 f'(Фолд),'p2 cc 20'(Колл 20),'p3 cbr 100'(Рейз до 100). - Дилер:
'd dh p1 AsKs'(Раздать карманные),'d db AhKhQh'(Раздать на борд). - Мета:
'p4 m Hello!'(Сообщение).
Этот человекочитаемый формат служит как для передачи данных по API, так и для журнала аудита.