851: Пакет/Покерный UI
- Требуется:
- Совместим с:
Чисто функциональная React UI-библиотека для Движка Покера. Она строго следует парадигме "контролируемого компонента", отображая предоставленное ей состояние игры и отправляя действия обратно потребителю, не содержа при этом никакой бизнес-логики.
Пакет Покерный UI демонстрирует идеальную архитектуру для игровых интерфейсов в современной экосистеме с общим бэкендом. Он предоставляет полный, настраиваемый интерфейс покерного стола, который делегирует всю доменную логику Движку Покера.
Философия
Этот проект обеспечивает строгое разделение между представлением и логикой:
- Чистое Представление: UI не содержит никакой игровой логики. Он не вычисляет победителей, не следит за соблюдением правил и не управляет очередностью ходов. Он просто отображает
Состояние, предоставленное движком. - Контролируемый Ввод: Следуя паттерну React "контролируемый компонент" (например,
<input value={...} onChange={...} />), основной компонент<PokerGame />принимает свойствоstateи вызываетonStateChange(или отправляет команды) при взаимодействии с пользователем. - Регистрируемый Движок: Он полностью полагается на Движок Покера для доменной логики, гарантируя, что фронтенд и бэкенд используют один и тот же набор правил.
- Готовность к Сервису: Он сразу совместим с Игровым Сервисом, что обеспечивает бесшовную многопользовательскую интеграцию.
Архитектура
Архитектура основана на однонаправленном потоке данных, где бэкенд (или локальный экземпляр движка) является единственным источником истины.
Такое разделение ответственности открывает ключевые возможности:
- Оптимистичные Обновления: Действия могут применяться локально для мгновенной обратной связи в ожидании подтверждения от сервера.
- Повторяемость: В UI можно передать историю состояний, чтобы в точности воспроизвести раздачу.
- Тестируемость: UI можно тестировать со статическими JSON-фикстурами, не имитируя сложную игровую логику.
Использование
Основной абстракцией является компонент <PokerGame />. Ему требуется объект state (соответствующий интерфейсу State Движка) и обработчик событий.
import React, { useState } from 'react';
import * as Poker from '@idealic/poker-engine';
import { PokerUI } from '@idealic/poker-ui';
import '@idealic/poker-ui/src/style.scss';
const App = () => {
// 1. Инициализация состояния (обычно с бэкенда)
const [state, setState] = useState<Poker.State>(initialState);
const handleStateChange = (newState: Poker.State) => {
// 2. Оптимистичное обновление локального состояния
setState(newState);
// 3. Отправка действия на бэкенд (концептуально)
// api.sendAction(newState.lastAction);
};
return (
<PokerUI
state={state}
onStateChange={handleStateChange}
author="Player1" // Перспектива для рендеринга (карманные карты и т. д.)
options={{
buyIn: 1000,
}}
/>
);
};
Интеграция с Игровым Сервисом
При совместном использовании с Игровым Сервисом поток делегирует обработку бэкенду:
// ... внутри вашего компонента
const handleStateChange = async (newState: Poker.State) => {
// Сервис обрабатывает состояние (проверяя логику, переходя к следующим улицам)
const processed = await Service.process(newState);
setState(processed);
};
Кастомизация
UI разработан с учетом расширяемости. Отдельные подкомпоненты можно переопределить через свойство components, сохраняя при этом общую структуру и логику.
import { PokerUI, Card } from '@idealic/poker-ui';
// Пользовательский компонент карты
const MyCustomCard = props => <div className="my-fancy-card">{props.card}</div>;
<PokerUI
state={state}
components={{
Card: MyCustomCard, // Переопределить компонент Card
// Chips, Player, Board и др. также могут быть переопределены
}}
/>;
Стилизация
Стили по умолчанию предоставляются в файле src/style.scss и используют BEM-нотацию (например, .poker-player, .poker-card) для упрощения переопределения с помощью стандартного CSS.