4.3 KiB
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
数据输入
视图支持三种输入方式:
- 填写核心游戏服务地址和
game_id,点击“获取”。 前端请求自身的/api/fetch-game?base_url=...&game_id=...,由回放服务去访问核心服务的/games/{game_id},避免浏览器跨域限制。 - 上传静态 JSON 文件。 文件在浏览器本地解析,不依赖核心服务。
- 开启自动获取。
按指定秒数轮询同一个核心服务和
game_id,用于观察正在运行的游戏快照。新快照会先尝试和当前回放位置合并;如果当前手牌追加了 action、showdown 或 award,回放会接续到新增 frame,而不是重头播放。
/api/fetch-game 也支持传入完整 url,便于未来接入网关或静态 JSON 服务。
数据模型与归一化
当前游戏详情返回结构包含:
players:玩家最终状态。hands:历史手牌列表。- 每手
actions:行动记录,包含street、player_id、action、amount、行动后street_bet和stack。 awards:底池分配。showdown_hands:摊牌玩家手牌。
前端不会依赖核心服务内部对象,只读取 JSON 字段并做归一化:
- 根据
players和actions得到座位顺序。 - 从
starting_stack开始,按历史actions.stack和awards推演每手牌开始时的筹码。 - 每手牌生成一组离散 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.engine、service 或 Agent 代码,也不要求游戏服务开放 CORS。未来可以单独部署在 CDN + 轻量代理、容器或任意 Python 运行环境中。
后续适配
- 核心服务返回非 showdown 玩家手牌后,只需要让每手 JSON 包含
hole_cards或private_hands映射,前端现有归一化会优先读取。 - 如果服务端未来提供增量事件流,可以在
app.js增加一个 source adapter,把事件流转成同样的 frame 列表,动画层无需重写。