851: Пакет/Интерфейс для Покера
- Требует:
- Совместим с:
Это библиотека, которая отвечает только за внешний вид игры в покер. Она работает по простому принципу: ей показывают, как выглядит игра в данный момент (кто какие карты держит, сколько фишек на столе), и она это рисует. Когда игрок что-то делает (например, ставит фишку), интерфейс не решает, правильно это или нет, а просто сообщает об этом действии основной программе. В самом интерфейсе нет никаких правил игры.
Пакет Интерфейс для Покера — это хороший пример того, как нужно создавать «лицо» игры в современном мире, где вся логика находится на общем сервере. Он даёт готовый стол для покера, который можно настроить по своему вкусу, при этом все «мозги» игры — правила, подсчёт очков — передаются специальному Движку для Покера.
Принцип работы
Главная идея этого проекта — строго разделить внешний вид и «мозги» игры:
- Только картинка: В интерфейсе нет никакой логики игры. Он не считает, кто победил, не следит за правилами и не определяет, чей сейчас ход. Он просто рисует то, что ему присылает движок — текущее состояние игры.
- Управляемый ввод: Интерфейс похож на марионетку. Главный компонент
<PokerGame />получает «команду», как ему выглядеть (state), а когда игрок что-то делает, он просто сообщает об этом черезonStateChange. Он не принимает решений сам. - Подключаемый движок: Интерфейс полностью доверяет Движку для Покера. Это гарантирует, что правила игры будут одинаковыми и для игрока, и для сервера.
- Готов к работе в сети: Его можно легко подключить к Игровому Сервису, чтобы играть с другими людьми по сети.
Как это устроено
Вся система работает по принципу одностороннего движения данных. Главный источник правды — это сервер, который решает, что происходит в игре.
Такое разделение даёт несколько крутых возможностей:
- Быстрый отклик: Действия игрока можно показать на экране мгновенно, не дожидаясь ответа от сервера. Это делает игру плавной.
- Повтор игры: Можно «скормить» интерфейсу всю историю состояний игры, и он в точности покажет, как проходила партия.
- Лёгкое тестирование: Интерфейс можно проверить, просто показывая ему заранее подготовленные состояния игры. Не нужно запускать всю сложную игровую логику.
Как использовать
Главная часть — это компонент <PokerGame />. Ему нужно всего две вещи: объект с текущим состоянием игры и «слушатель», который будет реагировать на действия игрока.
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);
};
Настройка
Интерфейс легко расширять. Можно заменить отдельные его части (например, карты или фишки) своими собственными, не ломая общую структуру.
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
// Так же можно заменить фишки, игрока, стол и т.д.
}}
/>;
Стили
Стандартные стили находятся в файле src/style.scss. Они используют специальную систему именования, чтобы было легко менять внешний вид с помощью обычного CSS.