- 后端实现最小正式版过水不胡规则:玩家在响应窗口选择PASS后,直到下次摸牌前不能响应胡 - 完善GameSeat状态管理,新增passedHuBlocked字段及相关方法 - 在ResponseActionWindowBuilder和GameActionProcessor中增加过水不胡校验 - 前端重构动作面板,区分回合动作和响应动作,支持多用户视角切换 - 优化公共事件处理逻辑,自动清理失效的私有动作面板 - 更新相关文档说明当前实现的规则范围和工程取舍 - 补充测试用例验证过水不胡规则的正确性
20 KiB
XueZhanMaster 详细开发计划
本文档是项目主计划文档,用于后续新对话、新迭代或新成员接手时快速建立完整上下文。
它不仅描述“要做什么”,还描述“为什么这样做”“当前做到哪一步”“接下来应该怎么接”。
当前状态快照日期:2026-03-20
1. 项目定义
1.1 项目名称
- 中文名:
血战大师 - 英文名:
XueZhanMaster
1.2 项目定位
XueZhanMaster 是一个面向四川麻将血战到底玩家的 AI 训练平台。
这个项目至少要同时具备三种核心能力:
-
对局能力
支持真人与 AI 混合对局,支持真人邀请,支持缺人时 AI 补位,支持配置补位 AI 强度。 -
教学能力
在局中给出建议动作、解释理由,并允许每个真人玩家独立开启或关闭自己的 AI 教学。 -
成长能力
在局后生成个人复盘,标注关键失误,沉淀错题,支持后续针对性训练。
1.3 核心差异点
这个项目和普通麻将游戏的关键差异不在“能不能打牌”,而在以下几点:
- 教学建议是玩家私有的,不是公共广播
- 教学必须基于玩家可见信息,不能泄露隐藏信息
- AI 不只是陪打,还要承担“训练”和“成长反馈”的角色
- H5 不是简化端,而是正式交付终端
2. 产品目标与范围
2.1 最终目标
做成一个支持:
- 真人邀请
- AI 补位
- AI 强度配置
- 每位真人独立 AI 教学开关
- H5 与 PC Web 双端可用
- 局后个人复盘
- 错题本与成长记录
的四川麻将血战到底训练产品。
2.2 当前阶段目标
当前阶段的重点不是把所有能力一次做完,而是先完成最小可运行闭环:
- 真人房间流可用
- 单局规则主干可用
- AI 可补位并自动推进回合
- H5 页面可完整操作
- WebSocket 公共/私有消息通道建立
2.3 当前明确不在范围内
以下内容当前不作为优先交付目标:
- 支付与会员
- 排位与段位系统
- 排行榜
- 多玩法麻将
- 社交关系链
- 原生 App
- 强化学习训练平台
- 完整的断线托管与观战体系
这样做是为了遵守 YAGNI,避免在规则主干还未稳定时引入高复杂度系统。
3. 用户、场景与验收口径
3.1 核心用户
新手训练用户
目标:
- 想知道当前该打什么牌
- 想知道为什么这样打更合理
- 希望边打边学
验收口径:
- 能在 H5 中建房或入房
- 能在对局中看到自己的私有教学建议
- 能手动开关自己的教学
有基础的进阶用户
目标:
- 想和不同强度 AI 对练
- 想复盘某次关键选择是否合理
验收口径:
- 可选择 AI 强度
- 局后可查看个人视角复盘
- 可看到关键失误点和替代打法
朋友组局用户
目标:
- 邀请真人朋友一起打
- 缺人时由 AI 自动补位
验收口径:
- 房主可建房、邀请、开局
- 不满 4 人时自动补 AI
- 真人玩家各自拥有独立教学设置
3.2 核心使用链路
链路 A:训练型单局
- 建房
- 选择 AI 补位与强度
- 开局
- 定缺
- 出牌与吃碰杠胡响应
- 获得私有建议
- 局后复盘
链路 B:真人邀请局
- 房主建房
- 发送房间码或邀请链接
- 真人加入
- 不足 4 人自动补 AI
- 每位真人按自己需求开关教学
- 对局结束后各自查看个人复盘
4. 终端范围与 H5 要求
4.1 必须支持的终端
项目必须同时支持:
PC WebH5 Web
4.2 H5 的项目地位
H5 是正式交付范围,不是附带兼容项。
这意味着:
- 功能设计必须考虑移动端单手操作
- 页面布局必须移动端优先
- 教学提示必须考虑移动端遮挡问题
- 实时消息必须考虑移动网络环境和重连
4.3 H5 具体要求
交互要求
- 不依赖 hover 才能触发关键操作
- 核心按钮点击热区足够大
- 建房、入房、准备、开局、定缺、出牌都可在 H5 完整操作
- 局内弹层不能遮挡核心出牌区域过久
布局要求
360px至430px宽度下正常使用- 竖屏优先
- 关键操作不被浏览器底栏、刘海、安全区遮挡
- 私有教学区与公共牌桌区视觉边界明确
性能要求
- 首屏轻量
- 避免无意义的大动画
- 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 教学建议、玩家可见状态
web 演示或基础接口
ws WebSocket 配置与消息发布
6.2 当前前端结构
当前前端仍以单页面原型为主,但已经承担三类职责:
- H5 房间流操作
- 对局状态展示
- WebSocket 消息接收与展示
后续建议按页面拆分为:
HomePageRoomPageGamePageReviewPage
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 原型页向正式对局页演进的规划和拆解
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_SUITDISCARDPENGGANGHUPASS
-
POST /api/games/{gameId}/lack- 兼容接口
-
POST /api/games/{gameId}/discard- 兼容接口
8.3 演示与健康检查
GET /api/demo/tableGET /api/demo/adviceGET /api/health
8.4 当前实时主题
公共主题
/topic/games/{gameId}/events
私有动作主题
/topic/users/{userId}/actions
私有教学主题
/topic/users/{userId}/teaching
9. 领域拆解与后续数据规划
9.1 核心领域对象
房间域
- 房间
- 座位
- 房主
- 准备状态
- 邀请与加入关系
对局域
- 对局会话
- 座位状态
- 当前阶段
- 当前轮次
- 动作候选
- 事件流
教学域
- 玩家可见状态
- 推荐动作
- 推荐理由
- 教学开关
- 教学展示模式
成长域
- 个人复盘
- 关键失误点
- 决策日志
- 错题本
9.2 数据库规划
当前仍以内存态运行,后续必须落库。建议按以下表结构推进:
用户相关
userplayer_preference
房间相关
roomroom_seat
对局相关
game_sessiongame_seatgame_stepdecision_log
教学与复盘
game_private_reviewmistake_book
9.3 落库优先级
第一优先级
roomroom_seatgame_session
第二优先级
game_stepdecision_log
第三优先级
game_private_reviewmistake_book
10. AI 能力与模型接入规划
10.1 AI 在本项目中的职责
AI 不是单一模块,而是三层能力:
-
补位对局 AI
负责真实对局中代替真人行动。 -
局中教学 AI
负责在玩家自己的视角下给出动作建议和解释。 -
局后复盘 AI
负责总结关键转折点、错误选择和改进建议。
10.2 推荐技术路线
路线 A:规则引擎优先,LLM 做解释层
做法:
- 对局合法性、基础策略、可行动作由规则引擎和启发式策略决定
- LLM 只负责把建议解释成人能理解的话术
优点:
- 成本低
- 响应稳定
- 可控性强
缺点:
- 解释的“聪明程度”受规则层质量影响
推荐度:最高
路线 B:规则引擎 + 小模型评分 + LLM 解释
做法:
- 对若干候选动作做特征评分
- 用轻量模型或策略打分辅助排序
- LLM 负责解释和复盘生成
优点:
- 决策质量更高
- 更适合后期成长系统
缺点:
- 研发成本高于路线 A
推荐度:中期演进路线
路线 C:LLM 直接决策
做法:
- 直接把局面喂给大模型,让其决定出什么牌
缺点:
- 成本高
- 稳定性差
- 时延较高
- 容易不一致
推荐度:当前不推荐
10.3 当前推荐的 AI Provider 策略
教学解释与复盘
推荐优先采用“低成本文本模型”:
- 适合生成短解释、复盘摘要、错题分析
- 可按 token 成本控制单局费用
补位 AI
当前不建议直接依赖大模型实时决策,优先本地规则策略或后端启发式策略。
成本控制原则
- 对局实时动作尽量不调用外部大模型
- 教学解释按需生成,不必每步都生成长文
- 复盘可在局后异步生成
11. 阶段规划与里程碑
M1 房间流与单局主干
目标:
- 建立真实可运行的最小房间流和单局主干
范围:
- 建房、入房、准备、开局
- 定缺
- 出牌
- AI 自动推进
- 公私消息基本分离
退出标准:
- 真人可走完最小单局主流程
- 不足 4 人时能自动补 AI
- H5 原型可操作
当前状态:
- 已基本完成
M2 动作系统扩展
目标:
- 将当前动作系统从“定缺 + 出牌”扩展成真正的麻将动作系统
范围:
PENGGANGHUPASS- 响应窗口
- 优先级裁决
- 动作候选推送
退出标准:
- 对手打牌后能正确生成响应候选
- 可按优先级完成响应裁决
- 动作仍统一经由同一入口
当前状态:
- 已基本完成
M3 规则与结算
目标:
- 让血战到底规则真正闭环
范围:
- 胡牌判定
- 杠分
- 局终处理
- 基础结算
- 血战到底的继续对局规则
退出标准:
- 能完成一局完整结算
- 结算记录可供后续复盘使用
当前状态:
- 进行中
M4 H5 正式对局体验
目标:
- 从“操作台”升级为真正可用的 H5 对局页
范围:
- 牌桌布局
- 手牌区与动作区
- 私有教学面板
- 弱网与重连体验
- 页面拆分
退出标准:
360px到430px宽度可稳定使用- 局内主流程无需依赖开发者视图
- 公共事件与私有教学信息展示清晰
当前状态:
- 进行中
M5 教学系统扩展
目标:
- 支持独立教学开关和更完整的教学体验
范围:
- 教学开关接口
- 私有教学模式切换
- 短解释 / 长解释模式
- 对局中即时建议
退出标准:
- 每位真人玩家可独立开关 AI 教学
- 不影响其他玩家的体验和消息
当前状态:
- 骨架已存在,待完成
M6 持久化与稳定性
目标:
- 从原型态进入可持续迭代态
范围:
- 房间与会话落库
- 关键步骤日志
- WebSocket 鉴权
- 基础重连恢复
退出标准:
- 关键状态可恢复
- 关键行为有日志与问题追踪基础
当前状态:
- 待做
M7 复盘与成长闭环
目标:
- 建立训练闭环
范围:
- 局后个人复盘
- 决策日志
- 错题本
- 成长记录
退出标准:
- 每局可生成个人复盘
- 可沉淀可回看的错误案例
当前状态:
- 待做
12. 测试、验收与发布前检查
12.1 后端最小验证
必须保持通过:
- 房间创建测试
- 房间加入与准备测试
- 开局测试
- 定缺测试
- 出牌与 AI 自动推进测试
执行命令:
cd backend
mvn test
12.2 前端最小验证
当前必须保持通过:
cd frontend
npm run build
12.3 H5 手工验收
至少验证以下流程:
- 建房
- 入房
- 准备
- 开局
- 定缺
- 出牌
- WebSocket 公共事件可见
- WebSocket 私有动作和教学消息可见
12.4 H5 验收视口
360x800390x844430x932
12.5 每阶段发布前检查
- 是否破坏统一动作入口
- 是否破坏公私消息边界
- 是否存在教学泄露隐藏信息风险
- 是否在 H5 下可操作
- 是否已补最小测试或手工验收记录
13. 非功能要求
13.1 安全
- 教学输入必须严格基于玩家视角
- 后续登录接入后,WebSocket 主题需与用户身份绑定
- 日志中避免直接打印敏感上下文或完整私人教学内容
13.2 性能
- 局中高频动作不依赖外部大模型
- WebSocket 消息体保持轻量
- H5 端避免全量重绘和大体积状态同步
13.3 可观测性
- 关键动作应有事件日志
- 后续应增加错误码、动作链路日志、关键统计指标
- 需要能够追踪“用户做了什么、系统为什么给出某建议”
13.4 可维护性
- 继续保持单体分包,先稳住边界再考虑拆分
- 统一动作入口和统一事件模型必须持续维持
- 文档、看板、Issue 模板需与代码演进同步更新
14. 风险与控制方案
风险 1:教学泄露隐藏信息
控制方案:
- 所有教学输入统一来自
PlayerVisibleGameState - 教学服务不得读取完整隐藏手牌快照
风险 2:动作系统继续分叉
控制方案:
- 所有新动作统一接入
GameActionProcessor - 新增动作前先补动作枚举、候选生成、优先级裁决说明
风险 3:H5 页面复杂度失控
控制方案:
- 移动端优先
- 页面按“房间 / 对局 / 复盘”拆分
- 长文本默认折叠
风险 4:WebSocket 未鉴权
控制方案:
- 当前仅作为原型
- 后续登录后统一接用户身份与私有主题授权
风险 5:数据库未接入导致状态丢失
控制方案:
- 在动作系统主干稳定后优先接房间与游戏会话落库
风险 6:AI 成本失控
控制方案:
- 实时对局动作不依赖外部大模型
- 解释与复盘按需生成
- 长文本解释可异步化
15. 文档体系与协作方法
15.1 文档关系
- 本文档:定义总目标、边界、阶段、风险、验收口径
PHASE_TASK_BOARD.md:把阶段目标拆成带状态的阶段任务卡WEEKLY_PLAN_BOARD.md:把近期执行拆成按周推进的工作节奏ISSUE_TEMPLATES_BOARD.md:把单个任务的立项模板和看板推进方式固化下来SPRINT_01_ISSUES_BOARD.md:把当前最优先的 Week 1 / Week 2 工作直接展开成可执行 IssueRESPONSE_RESOLUTION_RULES.md:把响应窗口、优先级、同优先级冲突处理和 V1 工程取舍写清楚
15.2 建议协作节奏
- 先在主计划中确认当前阶段
- 到阶段看板中选择待推进任务
- 按周计划确定最近 1 到 2 周目标
- 用 Issue 模板创建具体任务,或直接从 Sprint 看板领取现成任务
- 开发完成后同步更新看板状态
15.3 看板状态定义
待做:已确认要做,但尚未开始进行中:已经开始,正在开发、联调或补文档已完成:功能、文档或模板已形成稳定成果,可供继续复用
16. 新对话接手建议
如果后续开启新对话,建议顺序如下:
- 先看本文件,确认当前项目目标和阶段位置
- 再看阶段看板,确认哪些是进行中、哪些是待做
- 再看周计划,确认最近一周应优先推进什么
- 再看 Sprint 1 Issue 看板,确认当前真实待办
- 最后按 Issue 模板扩展新任务
关键代码入口建议优先阅读:
RoomServiceGameActionProcessorGameSessionServiceGameMessagePublisherfrontend/src/App.vue
若当前任务是动作系统,优先关注:
- 统一动作入口
- 响应候选生成
- 动作优先级裁决
若当前任务是 H5,优先关注:
- 页面拆分
- WebSocket 订阅状态
- 私有教学展示
- 弱网与重连体验
17. 配套文档
配套看板文档如下:
docs/PHASE_TASK_BOARD.mddocs/WEEKLY_PLAN_BOARD.mddocs/ISSUE_TEMPLATES_BOARD.mddocs/SPRINT_01_ISSUES_BOARD.mddocs/RESPONSE_RESOLUTION_RULES.md
这些文档用于把主计划拆成更细的执行层内容,并提供实际推进时的状态管理结构。