Files
texas_hold_x/docs/replay_view_design.md
2026-05-13 17:35:46 +08:00

4.3 KiB

Texas Hold X 回放视图设计方案

目标

构建一个与核心游戏服务和 Agent 解耦的独立 Web 服务,用于读取游戏详情 JSON 并以动画方式回放 Texas Hold'em 对局。它可以部署在任意能运行 Python 标准库 HTTP 服务的环境中,不要求核心服务增加前端路由,也不改变 Human HTTP Agent / AI HTTP Agent 协议。

架构

新增 texas_holdem_replay 包:

  • texas_holdem_replay.server:标准库 HTTP 服务,负责托管静态前端文件,并提供 /api/fetch-game 抓取代理。
  • texas_holdem_replay/static/index.html:独立页面入口。
  • texas_holdem_replay/static/styles.css:像素风牌桌、卡牌、座位和响应式布局。
  • texas_holdem_replay/static/app.js:数据归一化、手牌时间轴生成、动画播放、上传 JSON、手动抓取和自动轮询。

运行方式:

python -m texas_holdem_replay.server --host 127.0.0.1 --port 8088

也可以通过安装后的脚本启动:

texas-holdem-replay --host 127.0.0.1 --port 8088

数据输入

视图支持三种输入方式:

  1. 填写核心游戏服务地址和 game_id,点击“获取”。 前端请求自身的 /api/fetch-game?base_url=...&game_id=...,由回放服务去访问核心服务的 /games/{game_id},避免浏览器跨域限制。
  2. 上传静态 JSON 文件。 文件在浏览器本地解析,不依赖核心服务。
  3. 开启自动获取。 按指定秒数轮询同一个核心服务和 game_id,用于观察正在运行的游戏快照。新快照会先尝试和当前回放位置合并;如果当前手牌追加了 action、showdown 或 award,回放会接续到新增 frame,而不是重头播放。

/api/fetch-game 也支持传入完整 url,便于未来接入网关或静态 JSON 服务。

数据模型与归一化

当前游戏详情返回结构包含:

  • players:玩家最终状态。
  • hands:历史手牌列表。
  • 每手 actions:行动记录,包含 streetplayer_idactionamount、行动后 street_betstack
  • awards:底池分配。
  • showdown_hands:摊牌玩家手牌。

前端不会依赖核心服务内部对象,只读取 JSON 字段并做归一化:

  • 根据 playersactions 得到座位顺序。
  • starting_stack 开始,按历史 actions.stackawards 推演每手牌开始时的筹码。
  • 每手牌生成一组离散 frame:开局、跨街发公共牌、玩家行动、摊牌、结算。
  • 每个 frame 都有稳定 key。上传 JSON、手动获取和自动获取都会复用同一套合并逻辑:同一 game_id 且能找到当前手牌时,保留当前 frame;如果用户停在最新进度末尾,且当前手牌或后续手牌出现新增 frame,则从当前位置接续播放增量。用户正在查看历史手牌时,不会被新轮询强制跳走。
  • 非 showdown 玩家手牌显示卡背。
  • 已预留 hand.hole_cards[player_id]hand.private_hands[player_id] 兼容点,后续核心服务返回非 showdown 手牌时可直接展示。

动画与交互

牌桌采用卡通像素风格:

  • 椭圆绿色牌桌、木质像素边框、像素筹码状态条。
  • 玩家围绕牌桌分布,当前行动玩家高亮并显示冒泡文字。
  • 公共牌按 flop / turn / river 分阶段发出。
  • 动作之间默认保留约 1.1-1.5 秒间隔,用户可用“节奏”滑杆调慢或调快。
  • 支持上一帧、下一帧、播放/暂停、重置、选择指定手牌。

响应式设计

桌面端为三栏布局:数据控制、牌桌、事件日志。中等屏幕下事件日志下移,手机和平板窄屏下改为单列,牌桌高度固定到可观看的移动端比例,座位尺寸通过 CSS clamp 控制,避免文字和控件溢出。

解耦边界

回放服务只消费核心服务的公开 HTTP JSON,不导入 texas_holdem.engineservice 或 Agent 代码,也不要求游戏服务开放 CORS。未来可以单独部署在 CDN + 轻量代理、容器或任意 Python 运行环境中。

后续适配

  • 核心服务返回非 showdown 玩家手牌后,只需要让每手 JSON 包含 hole_cardsprivate_hands 映射,前端现有归一化会优先读取。
  • 如果服务端未来提供增量事件流,可以在 app.js 增加一个 source adapter,把事件流转成同样的 frame 列表,动画层无需重写。