Files
xzmaster/docs/SPRINT_01_ISSUES_BOARD.md
hujun 36dcfb7d31 feat: 实现麻将游戏结算系统与自摸胡功能
新增结算类型枚举和分数变更记录模型
补全响应裁决器与结算服务,支持点炮胡、自摸胡和明杠结算
扩展座位模型,增加已胡状态和分数字段
完善胡牌评估器,支持自摸胡判断
前端原型页增加分数显示和已胡状态
更新SPRINT文档记录当前进度
2026-03-20 13:58:16 +08:00

353 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# XueZhanMaster Sprint 1 Issue 看板
本文档把当前最优先的 `Week 1``Week 2` 工作直接拆成真实可执行任务。
当前状态快照日期:`2026-03-20`
Sprint 目标:
- 把动作系统从“只支持定缺和出牌”扩展为“可以承接麻将主干动作”
- 为后续响应优先级裁决建立候选动作模型
- 为 H5 正式对局页拆分准备稳定的数据结构和页面结构
---
## 1. 使用说明
### 1.1 本文档解决什么问题
- 当前这一轮开发先做哪几件事
- 哪些任务已经开始,哪些还没开始
- 每个任务的前后依赖关系是什么
- 每个任务做完之后如何验收
### 1.2 看板状态定义
- `待做`:已进入本次 Sprint但尚未开始
- `进行中`:当前优先推进中的任务
- `已完成`:本次 Sprint 内已完成并可供后续任务依赖
### 1.3 执行顺序建议
1. 先完成后端动作模型扩展
2. 再完成动作校验与事件扩展
3. 再定义响应候选和私有动作消息体
4. 最后输出 H5 页面拆分和动作面板结构
这样安排遵守:
- `KISS`:先稳住后端动作语义,再扩前端页面
- `YAGNI`:本轮不直接冲结算和持久化
- `SOLID`:规则、动作、消息、前端结构按职责拆开推进
- `DRY`:统一动作入口和统一消息模型,不走分叉
---
## 2. 待做
### S1-08 [H5] 对局页信息架构与页面拆分方案
## 背景
当前 `App.vue` 是原型操作台,已经能跑主流程,但信息和状态都堆在单页里。后续如果不先定义页面结构,动作系统一扩展,前端会迅速失控。
## 目标
输出 H5 正式对局页拆分方案,明确:
- 房间页、对局页、复盘页的职责
- 对局页内的信息分区
- 私有教学面板和动作面板层级
- 公共事件区与私有区边界
## 范围
- 页面职责定义
- 组件拆分建议
- 状态归属建议
- 移动端布局区块说明
## 非范围
- 不在本任务里实现完整 UI
- 不在本任务里处理所有视觉细节
## 依赖
- `S1-05`
## 产出物
- 页面拆分文档
- 信息架构草图说明
- 下一轮前端任务拆分建议
## 验收标准
- 下一轮前端改造可以按本文档直接开始
- 公共区、私有区、动作区职责清楚
## 验证方式
- 文档评审
- 与当前 H5 要求、周计划和阶段看板一致
---
## 3. 进行中
### S1-00 [Epic] 动作系统与 H5 页面拆分准备
## 背景
当前项目已经完成房间流、开局、定缺、出牌、AI 自动推进和实时消息骨架,但动作系统仍停留在最小主干。要继续推进 `PENG / GANG / HU / PASS` 和正式 H5 对局页,必须先完成本轮 Sprint。
## 阶段目标
- 动作系统具备扩展主干
- 私有候选动作模型可表达响应窗口
- H5 下一轮页面拆分有明确执行输入
## 关键交付
- 动作枚举与请求体扩展
- 动作校验与事件扩展
- 私有动作消息体扩展
- 响应裁决规则澄清
- H5 页面拆分方案
## 不做范围
- 不做完整胡牌结算
- 不做数据库持久化
- 不做完整 H5 视觉还原
## 退出标准
- 后端已能承接新增动作类型
- 前端已知道如何接响应候选
- 下一轮 H5 正式页面改造可以直接开始
---
## 4. 已完成
### S1-BASE-01 [基础] 当前最小链路已打通
## 已完成内容
- 房间创建、加入、准备、开局
- 未满 4 人自动补 AI
- 定缺
- 真人出牌
- AI 自动推进回合
- 统一动作入口初版
- 公共事件与私有消息骨架
- H5 原型操作台
## 对 Sprint 1 的意义
这是本次 Sprint 的基础底座,后续所有任务都建立在这条最小链路上。
### S1-01 [功能] 统一动作入口支持 `PENG / GANG / HU / PASS` 基础请求模型
## 已完成内容
- `GameSessionService.performAction` 不再只在服务层硬编码放行 `SELECT_LACK_SUIT / DISCARD`
- 兼容接口 `lack / discard` 已复用统一动作入口
- `GameActionRequest` 已补轻量上下文字段 `sourceSeatNo`
- `PENG / GANG / HU / PASS` 已可进入统一动作处理链
- 当前未实现动作会由处理器统一返回 `GAME_ACTION_UNSUPPORTED`
- 补充了“新动作走统一入口”和“未知动作被拒绝”的测试
## 验收结果
- 新动作不再被服务层提前拦死
- 现有定缺和出牌链路未回归
- `mvn test` 已通过
### S1-02 [功能] 动作校验器与处理链扩展
## 已完成内容
- `PENG / GANG / HU / PASS` 已有独立处理分支入口
- 新增动作已补统一的阶段校验
- 新增动作已补统一的来源座位校验
- 需要目标牌的动作已补必填参数校验
- 当前可明确区分三类结果:
- 参数非法
- 时机非法
- 进入分支但动作尚未实现
- 已补充对应单元测试
## 验收结果
- 非法时机请求会返回 `GAME_PHASE_INVALID`
- 缺少来源座位或目标牌会返回 `GAME_ACTION_PARAM_INVALID`
- 合法进入分支的新增动作当前返回 `GAME_ACTION_UNSUPPORTED`
- `mvn test` 已通过
### S1-03 [功能] 事件模型扩展,覆盖新增动作语义
## 已完成内容
- `GameEventType` 已补齐:
- `RESPONSE_WINDOW_OPENED`
- `RESPONSE_WINDOW_CLOSED`
- `PENG_DECLARED`
- `GANG_DECLARED`
- `HU_DECLARED`
- `PASS_DECLARED`
- `GameEvent` 已新增统一事件工厂方法,覆盖:
- 开局
- 定缺
- 阶段切换
- 摸牌
- 弃牌
- 切换回合
- 未来响应窗口事件
- 未来响应动作事件
- 现有公共事件已改为复用统一工厂方法,不再在多处手工拼接载荷
- 已补充事件工厂测试,验证新增动作事件载荷格式
## 验收结果
- 事件模型已能表达新增动作语义
- 现有事件载荷格式更加统一
- 后续 `S1-04 / S1-05` 可以直接复用事件约定
- `mvn test` 已通过
### S1-04 [功能] 响应候选模型初版
## 已完成内容
- 新增响应候选领域模型:
- `ResponseActionOption`
- `ResponseActionSeatCandidate`
- `ResponseActionWindow`
- `GameSession` 已预留 `pendingResponseActionWindow` 字段,为后续真实响应流程挂载窗口对象做准备
- 新增 `ResponseActionWindowBuilder`,可基于一次弃牌构建候选窗口
- 当前候选规则支持:
- 手里 2 张同牌时生成 `PENG + PASS`
- 手里 3 张同牌时生成 `PENG + GANG + PASS`
- 已补单测验证:
- 有候选时可正确构建多座位响应窗口
- 无候选时返回空结果
## 验收结果
- 后端已经能表达“谁现在可以响应什么”
- `PASS` 已纳入候选动作模型
- 下一步 `S1-05` 可以直接把候选窗口映射到私有动作消息
- `mvn test` 已通过
### S1-05 [功能] 扩展私有动作消息体,支持响应候选下发
## 已完成内容
- `PrivateActionMessage` 已升级为结构化消息,补充字段:
- `actionScope`
- `windowId`
- `triggerEventType`
- `sourceSeatNo`
- `triggerTile`
- `candidates`
- 新增 `PrivateActionCandidate` DTO
- `GameMessagePublisher` 已拆分:
- `publishPrivateTurnActionRequired`
- `publishPrivateResponseActionRequired`
- 当前回合动作消息与响应候选消息已可共用同一消息结构
- 弃牌后若存在候选,后端已能真正创建响应窗口并下发私有候选动作消息
- AI 候选当前会自动提交 `PASS`
- 当前已接入初版响应裁决:
- 全员响应完成后按优先级和顺位决出单一赢家
- `PENG` 已可真实执行并夺取回合
- `GANG` 已可真实执行并补摸一张牌
- `HU` 已可进入候选、参与裁决并结束当前单局
- 已补消息发布单测,验证 turn / response 两类消息形状
## 验收结果
- 私有动作消息已经能区分“主动回合动作”和“被动响应动作”
- 前端后续无需再猜测候选字段语义
- `mvn test` 已通过
### S1-07 [功能] H5 动作面板字段对齐与占位接入
## 已完成内容
- `App.vue` 已对齐新的私有动作消息结构
- H5 原型页已支持识别:
- `TURN`
- `RESPONSE`
两类动作消息作用域
- 私有动作区已增加候选动作展示占位
- 私有动作区已增加来源座位、目标牌等上下文字段展示
- H5 原型页已支持点击候选动作按钮,并提交带 `sourceSeatNo` 的动作请求
- 当前已可通过点击 `PASS` 让响应窗口恢复行牌
- 当前已可通过点击 `PENG / GANG` 候选按钮参与真实响应裁决
- 已补样式支持候选动作标签展示
## 验收结果
- H5 原型页已经能消费结构化私有动作消息
- 当前定缺和出牌流程未被破坏
- `npm run build` 已通过
### S1-06 [研究] 响应优先级裁决规则澄清
## 已完成内容
- 新增规则澄清文档 `docs/RESPONSE_RESOLUTION_RULES.md`
- 明确了本项目 `V1` 的响应优先级:
- `HU > GANG > PENG > PASS`
- 明确了本项目 `V1` 的同优先级裁决:
- 按出牌者之后最近顺位优先
- 明确了本项目 `V1` 的工程取舍:
- 当前不实现完整 `过水不胡`
- 当前不实现 `一炮多响`
- 明确了公共消息与私有消息的职责边界
- 明确了后续真实响应窗口接入主流程的推荐顺序
## 验收结果
- 后续实现不需要再重新讨论优先级口径
- 裁决器实现已有单一依据
- 文档已纳入 README 与主计划索引
---
## 5. 依赖关系图
### 5.1 后端主线
`S1-01 -> S1-02 -> S1-03 -> S1-04 -> S1-05`
### 5.2 规则澄清主线
`S1-04 -> S1-06`
### 5.3 前端准备主线
`S1-05 -> S1-07 -> S1-08`
---
## 6. 推荐领取顺序
如果下一轮马上要开始做代码,建议按下面顺序领取:
1. `S1-01`
2. `S1-02`
3. `S1-03`
4. `S1-04`
5. `S1-05`
6. `S1-07`
7. `S1-06`
8. `S1-08`
原因:
- 先把后端动作主干做稳
- 再让前端能最小消费字段
- 最后输出裁决规则和页面结构文档,指导下一轮实现