Files
xzmaster/docs/DEVELOPMENT_PLAN.md
hujun faf87fe3d6 feat: 添加局后复盘服务与页面容器组件
新增复盘服务相关DTO、Controller和Service
实现复盘页面容器组件ReviewPageContainer
更新前端页面架构文档与开发计划
移除DemoGameController中的演示复盘接口
补充复盘服务单元测试
2026-03-20 16:50:49 +08:00

21 KiB
Raw Permalink Blame History

XueZhanMaster 详细开发计划

本文档是项目主计划文档,用于后续新对话、新迭代或新成员接手时快速建立完整上下文。
它不仅描述“要做什么”,还描述“为什么这样做”“当前做到哪一步”“接下来应该怎么接”。

当前状态快照日期:2026-03-20


1. 项目定义

1.1 项目名称

  • 中文名:血战大师
  • 英文名:XueZhanMaster

1.2 项目定位

XueZhanMaster 是一个面向四川麻将血战到底玩家的 AI 训练平台。

这个项目至少要同时具备三种核心能力:

  1. 对局能力
    支持真人与 AI 混合对局,支持真人邀请,支持缺人时 AI 补位,支持配置补位 AI 强度。

  2. 教学能力
    在局中给出建议动作、解释理由,并允许每个真人玩家独立开启或关闭自己的 AI 教学。

  3. 成长能力
    在局后生成个人复盘,标注关键失误,沉淀错题,支持后续针对性训练。

1.3 核心差异点

这个项目和普通麻将游戏的关键差异不在“能不能打牌”,而在以下几点:

  • 教学建议是玩家私有的,不是公共广播
  • 教学必须基于玩家可见信息,不能泄露隐藏信息
  • AI 不只是陪打,还要承担“训练”和“成长反馈”的角色
  • H5 不是简化端,而是正式交付终端

2. 产品目标与范围

2.1 最终目标

做成一个支持:

  • 真人邀请
  • AI 补位
  • AI 强度配置
  • 每位真人独立 AI 教学开关
  • H5 与 PC Web 双端可用
  • 局后个人复盘
  • 错题本与成长记录

的四川麻将血战到底训练产品。

2.2 当前阶段目标

当前阶段的重点不是把所有能力一次做完,而是先完成最小可运行闭环:

  1. 真人房间流可用
  2. 单局规则主干可用
  3. AI 可补位并自动推进回合
  4. H5 页面可完整操作
  5. WebSocket 公共/私有消息通道建立

2.3 当前明确不在范围内

以下内容当前不作为优先交付目标:

  • 支付与会员
  • 排位与段位系统
  • 排行榜
  • 多玩法麻将
  • 社交关系链
  • 原生 App
  • 强化学习训练平台
  • 完整的断线托管与观战体系

这样做是为了遵守 YAGNI,避免在规则主干还未稳定时引入高复杂度系统。


3. 用户、场景与验收口径

3.1 核心用户

新手训练用户

目标:

  • 想知道当前该打什么牌
  • 想知道为什么这样打更合理
  • 希望边打边学

验收口径:

  • 能在 H5 中建房或入房
  • 能在对局中看到自己的私有教学建议
  • 能手动开关自己的教学

有基础的进阶用户

目标:

  • 想和不同强度 AI 对练
  • 想复盘某次关键选择是否合理

验收口径:

  • 可选择 AI 强度
  • 局后可查看个人视角复盘
  • 可看到关键失误点和替代打法

朋友组局用户

目标:

  • 邀请真人朋友一起打
  • 缺人时由 AI 自动补位

验收口径:

  • 房主可建房、邀请、开局
  • 不满 4 人时自动补 AI
  • 真人玩家各自拥有独立教学设置

3.2 核心使用链路

链路 A训练型单局

  1. 建房
  2. 选择 AI 补位与强度
  3. 开局
  4. 定缺
  5. 出牌与吃碰杠胡响应
  6. 获得私有建议
  7. 局后复盘

链路 B真人邀请局

  1. 房主建房
  2. 发送房间码或邀请链接
  3. 真人加入
  4. 不足 4 人自动补 AI
  5. 每位真人按自己需求开关教学
  6. 对局结束后各自查看个人复盘

4. 终端范围与 H5 要求

4.1 必须支持的终端

项目必须同时支持:

  • PC Web
  • H5 Web

4.2 H5 的项目地位

H5 是正式交付范围,不是附带兼容项。

这意味着:

  • 功能设计必须考虑移动端单手操作
  • 页面布局必须移动端优先
  • 教学提示必须考虑移动端遮挡问题
  • 实时消息必须考虑移动网络环境和重连

4.3 H5 具体要求

交互要求

  • 不依赖 hover 才能触发关键操作
  • 核心按钮点击热区足够大
  • 建房、入房、准备、开局、定缺、出牌都可在 H5 完整操作
  • 局内弹层不能遮挡核心出牌区域过久

布局要求

  • 360px430px 宽度下正常使用
  • 竖屏优先
  • 关键操作不被浏览器底栏、刘海、安全区遮挡
  • 私有教学区与公共牌桌区视觉边界明确

性能要求

  • 首屏轻量
  • 避免无意义的大动画
  • WebSocket 消息触发的重绘尽量局部化
  • 弱网下具备可感知的重连和状态恢复提示

教学要求

  • 建议优先使用卡片、底部面板或抽屉
  • 长解释默认折叠,不覆盖核心牌桌
  • 私有教学与公共桌面事件必须明显区分

5. 架构原则与约束

5.1 核心工程原则

KISS

  • 当前采用单体应用按业务分包,不拆微服务
  • 动作系统先统一入口,再逐步补动作类型
  • H5 页面先完成高频主流程,再做视觉和交互细化

YAGNI

  • 当前不做支付、会员、排位、复杂社交
  • 当前不做复杂的多玩法规则引擎
  • 当前不先搭大而全的 AI 训练平台

SOLID

  • room 只管房间
  • game 只管对局、动作、阶段
  • strategy 只管推荐动作和 AI 决策
  • teaching 只管教学输出与玩家可见状态
  • ws 只管消息发布与订阅约定

DRY

  • 统一动作入口
  • 统一事件流
  • 统一玩家可见状态模型
  • 前后端统一阶段与动作枚举语义

5.3 注释与脚本约定

  • 后端新增或修改的业务代码,必须为复杂规则、关键字段、状态切换、结算口径和跨阶段流程补充适量中文注释,不能只保留方法名级别语义。
  • 前端新增或修改的页面、组件与状态逻辑,必须为复杂交互、实时消息消费、动作面板联动和视图状态切换补充适量中文注释,避免后续拆页或联调时理解断层。
  • 后续数据库表结构、迁移脚本、初始化 SQL、索引和存储过程也必须补充必要中文注释重点说明业务含义、约束原因、字段口径、回填策略和关键索引用途。
  • 注释要求遵守 KISS:可以适当多写,但只解释不直观的意图、约束、边界和取舍,不写“变量赋值”这类冗余注释。
  • 对以下高风险区域,中文注释默认视为必需项:麻将规则判断、结算分摊、响应裁决、实时消息边界、局终处理、数据迁移与回滚脚本。

5.2 最关键的系统约束

约束一:教学必须基于玩家可见状态

教学建议不能读取整桌隐藏手牌。
必须由 PlayerVisibleGameState 或等价的玩家视角模型作为输入。

约束二:公共消息和私有消息必须分离

  • 公共:桌面状态、公共动作、阶段变化
  • 私有:可行动作、教学建议、个人复盘

约束三:所有新动作统一进入动作系统

后续 PENG / GANG / HU / PASS 必须继续走统一动作入口,不能重新堆专用分支接口。

约束四H5 是一等公民

任何对局操作、教学、实时同步设计都不能默认只服务 PC。


6. 当前架构与代码结构

6.1 当前后端结构

common     统一返回、异常
room       房间、座位、加入、准备
game       对局、动作、状态、事件、动作处理
strategy   推荐动作、AI 决策
teaching   教学建议、玩家可见状态
review     局后复盘、错题与训练方向协议骨架
web        演示或基础接口
ws         WebSocket 配置与消息发布

6.2 当前前端结构

当前前端仍以 App.vue 作为页面容器,但已经从“单文件原型”开始向“可继续拆页的正式骨架”演进,当前承担三类职责:

  • H5 房间流操作
  • 对局状态展示
  • WebSocket 消息接收与展示

同时,已完成第一轮最小拆分准备:

  • 共享类型:frontend/src/types/game.ts
  • 复盘类型:frontend/src/types/review.ts
  • UI 格式化工具:frontend/src/utils/gameUi.ts
  • 展示组件:
    • frontend/src/components/AppShell.vue
    • frontend/src/components/RoomWorkspace.vue
    • frontend/src/components/GameWorkspace.vue
    • frontend/src/components/RoomControlPanel.vue
    • frontend/src/components/RoomLobbyPanel.vue
    • frontend/src/components/GameActionDock.vue
    • frontend/src/components/GameMessageStack.vue
    • frontend/src/components/PublicEventTimeline.vue
    • frontend/src/components/ViewSwitchPanel.vue
    • frontend/src/components/SelfHandPanel.vue
    • frontend/src/components/PublicSeatBoard.vue
  • 页面级容器目录已建立:
    • frontend/src/pages/RoomPageContainer.vue
    • frontend/src/pages/GamePageContainer.vue
    • frontend/src/pages/ReviewPageContainer.vue

后续建议按页面拆分为:

  • HomePage
  • RoomPage
  • GamePage
  • ReviewPage

6.3 当前消息结构

公共消息

  • /topic/games/{gameId}/events

私有动作消息

  • /topic/users/{userId}/actions

私有教学消息

  • /topic/users/{userId}/teaching

7. 当前已实现能力

7.1 后端已完成

  • 统一返回结构
  • 房间创建
  • 房间查询
  • 玩家加入房间
  • 真人准备
  • 房主开局
  • 未满 4 人自动补 AI
  • AI 强度枚举骨架
  • 生成内存态 GameSession
  • 真人定缺
  • 全员定缺后进入 PLAYING
  • 真人出牌
  • AI 自动推进回合直至轮回真人
  • 通用动作入口 POST /api/games/{gameId}/actions
  • 游戏事件骨架
  • WebSocket 配置和消息发布骨架

7.2 前端已完成

  • H5 房间流页面
  • 建房、入房、准备、开局、定缺、出牌
  • 公共桌面状态展示
  • WebSocket 公共事件订阅
  • WebSocket 私有动作订阅
  • WebSocket 私有教学订阅
  • /api/ws 代理配置
  • 正式动作面板与响应动作面板联调
  • 公共事件时间线与最近结算卡片
  • 教学推荐高亮与候选建议列表
  • 对局页信息架构文档与最小组件拆分基础

7.3 当前进行中

  • 动作系统从“定缺 + 出牌”扩展到真正的麻将动作系统
  • H5 页面容器继续向 RoomPage / GamePage / ReviewPage 拆分

7.4 当前已完成的文档治理

  • 文档体系已从单一主计划扩展为主计划 + 阶段看板 + 周计划 + Issue 模板
  • README 已补全文档索引与推荐阅读顺序

7.5 当前尚未完成

  • 自摸加番 / 加底等地方变体
  • 天胡、地胡
  • 更完整的地方化 过水不胡
  • 前端正式动作面板与规则联调
  • 教学开关接口
  • 局后个人复盘
  • 数据库持久化
  • WebSocket 鉴权
  • 断线重连恢复

8. 已实现接口与实时主题

8.1 房间接口

  • POST /api/rooms

    • 创建房间
  • GET /api/rooms/{roomId}

    • 查询房间详情
  • POST /api/rooms/{roomId}/join

    • 加入房间
  • POST /api/rooms/{roomId}/ready

    • 准备 / 取消准备
  • POST /api/rooms/{roomId}/start

    • 房主开局

8.2 对局接口

  • GET /api/games/{gameId}/state?userId=...

    • 获取玩家视角状态
  • POST /api/games/{gameId}/actions

    • 通用动作入口
    • 当前支持:
      • SELECT_LACK_SUIT
      • DISCARD
      • PENG
      • GANG
      • HU
      • PASS
  • POST /api/games/{gameId}/lack

    • 兼容接口
  • POST /api/games/{gameId}/discard

    • 兼容接口

8.3 演示与健康检查

  • GET /api/demo/table
  • GET /api/demo/advice
  • GET /api/health

8.4 当前实时主题

公共主题

  • /topic/games/{gameId}/events

私有动作主题

  • /topic/users/{userId}/actions

私有教学主题

  • /topic/users/{userId}/teaching

9. 领域拆解与后续数据规划

9.1 核心领域对象

房间域

  • 房间
  • 座位
  • 房主
  • 准备状态
  • 邀请与加入关系

对局域

  • 对局会话
  • 座位状态
  • 当前阶段
  • 当前轮次
  • 动作候选
  • 事件流

教学域

  • 玩家可见状态
  • 推荐动作
  • 推荐理由
  • 教学开关
  • 教学展示模式

成长域

  • 个人复盘
  • 关键失误点
  • 决策日志
  • 错题本

9.2 数据库规划

当前仍以内存态运行,后续必须落库。建议按以下表结构推进:

用户相关

  • user
  • player_preference

房间相关

  • room
  • room_seat

对局相关

  • game_session
  • game_seat
  • game_step
  • decision_log

教学与复盘

  • game_private_review
  • mistake_book

9.3 落库优先级

第一优先级

  • room
  • room_seat
  • game_session

第二优先级

  • game_step
  • decision_log

第三优先级

  • game_private_review
  • mistake_book

10. AI 能力与模型接入规划

10.1 AI 在本项目中的职责

AI 不是单一模块,而是三层能力:

  1. 补位对局 AI
    负责真实对局中代替真人行动。

  2. 局中教学 AI
    负责在玩家自己的视角下给出动作建议和解释。

  3. 局后复盘 AI
    负责总结关键转折点、错误选择和改进建议。

10.2 推荐技术路线

路线 A规则引擎优先LLM 做解释层

做法:

  • 对局合法性、基础策略、可行动作由规则引擎和启发式策略决定
  • LLM 只负责把建议解释成人能理解的话术

优点:

  • 成本低
  • 响应稳定
  • 可控性强

缺点:

  • 解释的“聪明程度”受规则层质量影响

推荐度:最高

路线 B规则引擎 + 小模型评分 + LLM 解释

做法:

  • 对若干候选动作做特征评分
  • 用轻量模型或策略打分辅助排序
  • LLM 负责解释和复盘生成

优点:

  • 决策质量更高
  • 更适合后期成长系统

缺点:

  • 研发成本高于路线 A

推荐度:中期演进路线

路线 CLLM 直接决策

做法:

  • 直接把局面喂给大模型,让其决定出什么牌

缺点:

  • 成本高
  • 稳定性差
  • 时延较高
  • 容易不一致

推荐度:当前不推荐

10.3 当前推荐的 AI Provider 策略

教学解释与复盘

推荐优先采用“低成本文本模型”:

  • 适合生成短解释、复盘摘要、错题分析
  • 可按 token 成本控制单局费用

补位 AI

当前不建议直接依赖大模型实时决策,优先本地规则策略或后端启发式策略。

成本控制原则

  • 对局实时动作尽量不调用外部大模型
  • 教学解释按需生成,不必每步都生成长文
  • 复盘可在局后异步生成

11. 阶段规划与里程碑

M1 房间流与单局主干

目标:

  • 建立真实可运行的最小房间流和单局主干

范围:

  • 建房、入房、准备、开局
  • 定缺
  • 出牌
  • AI 自动推进
  • 公私消息基本分离

退出标准:

  • 真人可走完最小单局主流程
  • 不足 4 人时能自动补 AI
  • H5 原型可操作

当前状态:

  • 已基本完成

M2 动作系统扩展

目标:

  • 将当前动作系统从“定缺 + 出牌”扩展成真正的麻将动作系统

范围:

  • PENG
  • GANG
  • HU
  • PASS
  • 响应窗口
  • 优先级裁决
  • 动作候选推送

退出标准:

  • 对手打牌后能正确生成响应候选
  • 可按优先级完成响应裁决
  • 动作仍统一经由同一入口

当前状态:

  • 已基本完成

M3 规则与结算

目标:

  • 让血战到底规则真正闭环

范围:

  • 胡牌判定
  • 杠分
  • 局终处理
  • 基础结算
  • 血战到底的继续对局规则

退出标准:

  • 能完成一局完整结算
  • 结算记录可供后续复盘使用

当前状态:

  • 进行中

M4 H5 正式对局体验

目标:

  • 从“操作台”升级为真正可用的 H5 对局页

范围:

  • 牌桌布局
  • 手牌区与动作区
  • 私有教学面板
  • 弱网与重连体验
  • 页面拆分

退出标准:

  • 360px430px 宽度可稳定使用
  • 局内主流程无需依赖开发者视图
  • 公共事件与私有教学信息展示清晰

当前状态:

  • 进行中

M5 教学系统扩展

目标:

  • 支持独立教学开关和更完整的教学体验

范围:

  • 教学开关接口
  • 私有教学模式切换
  • 短解释 / 长解释模式
  • 对局中即时建议

退出标准:

  • 每位真人玩家可独立开关 AI 教学
  • 不影响其他玩家的体验和消息

当前状态:

  • 骨架已存在,待完成

M6 持久化与稳定性

目标:

  • 从原型态进入可持续迭代态

范围:

  • 房间与会话落库
  • 关键步骤日志
  • WebSocket 鉴权
  • 基础重连恢复

退出标准:

  • 关键状态可恢复
  • 关键行为有日志与问题追踪基础

当前状态:

  • 待做

M7 复盘与成长闭环

目标:

  • 建立训练闭环

范围:

  • 局后个人复盘
  • 决策日志
  • 错题本
  • 成长记录

退出标准:

  • 每局可生成个人复盘
  • 可沉淀可回看的错误案例

当前状态:

  • 待做

12. 测试、验收与发布前检查

12.1 后端最小验证

必须保持通过:

  • 房间创建测试
  • 房间加入与准备测试
  • 开局测试
  • 定缺测试
  • 出牌与 AI 自动推进测试

执行命令:

cd backend
mvn test

12.2 前端最小验证

当前必须保持通过:

cd frontend
npm run build

12.3 H5 手工验收

至少验证以下流程:

  1. 建房
  2. 入房
  3. 准备
  4. 开局
  5. 定缺
  6. 出牌
  7. WebSocket 公共事件可见
  8. WebSocket 私有动作和教学消息可见

12.4 H5 验收视口

  • 360x800
  • 390x844
  • 430x932

12.5 每阶段发布前检查

  • 是否破坏统一动作入口
  • 是否破坏公私消息边界
  • 是否存在教学泄露隐藏信息风险
  • 是否在 H5 下可操作
  • 是否已补最小测试或手工验收记录

13. 非功能要求

13.1 安全

  • 教学输入必须严格基于玩家视角
  • 后续登录接入后WebSocket 主题需与用户身份绑定
  • 日志中避免直接打印敏感上下文或完整私人教学内容

13.2 性能

  • 局中高频动作不依赖外部大模型
  • WebSocket 消息体保持轻量
  • H5 端避免全量重绘和大体积状态同步

13.3 可观测性

  • 关键动作应有事件日志
  • 后续应增加错误码、动作链路日志、关键统计指标
  • 需要能够追踪“用户做了什么、系统为什么给出某建议”

13.4 可维护性

  • 继续保持单体分包,先稳住边界再考虑拆分
  • 统一动作入口和统一事件模型必须持续维持
  • 文档、看板、Issue 模板需与代码演进同步更新

14. 风险与控制方案

风险 1教学泄露隐藏信息

控制方案:

  • 所有教学输入统一来自 PlayerVisibleGameState
  • 教学服务不得读取完整隐藏手牌快照

风险 2动作系统继续分叉

控制方案:

  • 所有新动作统一接入 GameActionProcessor
  • 新增动作前先补动作枚举、候选生成、优先级裁决说明

风险 3H5 页面复杂度失控

控制方案:

  • 移动端优先
  • 页面按“房间 / 对局 / 复盘”拆分
  • 长文本默认折叠

风险 4WebSocket 未鉴权

控制方案:

  • 当前仅作为原型
  • 后续登录后统一接用户身份与私有主题授权

风险 5数据库未接入导致状态丢失

控制方案:

  • 在动作系统主干稳定后优先接房间与游戏会话落库

风险 6AI 成本失控

控制方案:

  • 实时对局动作不依赖外部大模型
  • 解释与复盘按需生成
  • 长文本解释可异步化

15. 文档体系与协作方法

15.1 文档关系

  • 本文档:定义总目标、边界、阶段、风险、验收口径
  • PHASE_TASK_BOARD.md:把阶段目标拆成带状态的阶段任务卡
  • WEEKLY_PLAN_BOARD.md:把近期执行拆成按周推进的工作节奏
  • ISSUE_TEMPLATES_BOARD.md:把单个任务的立项模板和看板推进方式固化下来
  • SPRINT_01_ISSUES_BOARD.md:把当前最优先的 Week 1 / Week 2 工作直接展开成可执行 Issue
  • RESPONSE_RESOLUTION_RULES.md:把响应窗口、优先级、同优先级冲突处理和 V1 工程取舍写清楚

15.2 建议协作节奏

  1. 先在主计划中确认当前阶段
  2. 到阶段看板中选择待推进任务
  3. 按周计划确定最近 1 到 2 周目标
  4. 用 Issue 模板创建具体任务,或直接从 Sprint 看板领取现成任务
  5. 开发完成后同步更新看板状态

15.3 看板状态定义

  • 待做:已确认要做,但尚未开始
  • 进行中:已经开始,正在开发、联调或补文档
  • 已完成:功能、文档或模板已形成稳定成果,可供继续复用

16. 新对话接手建议

如果后续开启新对话,建议顺序如下:

  1. 先看本文件,确认当前项目目标和阶段位置
  2. 再看阶段看板,确认哪些是进行中、哪些是待做
  3. 再看周计划,确认最近一周应优先推进什么
  4. 再看 Sprint 1 Issue 看板,确认当前真实待办
  5. 最后按 Issue 模板扩展新任务

关键代码入口建议优先阅读:

  • RoomService
  • GameActionProcessor
  • GameSessionService
  • GameMessagePublisher
  • frontend/src/App.vue

若当前任务是动作系统,优先关注:

  • 统一动作入口
  • 响应候选生成
  • 动作优先级裁决

若当前任务是 H5优先关注

  • 页面拆分
  • WebSocket 订阅状态
  • 私有教学展示
  • 弱网与重连体验

17. 配套文档

配套看板文档如下:

  • docs/PHASE_TASK_BOARD.md
  • docs/WEEKLY_PLAN_BOARD.md
  • docs/ISSUE_TEMPLATES_BOARD.md
  • docs/SPRINT_01_ISSUES_BOARD.md
  • docs/RESPONSE_RESOLUTION_RULES.md

这些文档用于把主计划拆成更细的执行层内容,并提供实际推进时的状态管理结构。