- 后端实现最小正式版过水不胡规则:玩家在响应窗口选择PASS后,直到下次摸牌前不能响应胡 - 完善GameSeat状态管理,新增passedHuBlocked字段及相关方法 - 在ResponseActionWindowBuilder和GameActionProcessor中增加过水不胡校验 - 前端重构动作面板,区分回合动作和响应动作,支持多用户视角切换 - 优化公共事件处理逻辑,自动清理失效的私有动作面板 - 更新相关文档说明当前实现的规则范围和工程取舍 - 补充测试用例验证过水不胡规则的正确性
388 lines
11 KiB
Markdown
388 lines
11 KiB
Markdown
# XueZhanMaster 响应优先级规则澄清
|
|
|
|
本文档用于澄清四川麻将血战到底在本项目中的响应窗口、优先级与裁决方式。
|
|
它不等于“所有地区、所有平台唯一正确规则”,而是:
|
|
|
|
1. 先吸收公开规则中的高共识部分
|
|
2. 再明确本项目 `V1` 的工程实现边界
|
|
3. 给后续真实裁决代码提供单一依据
|
|
|
|
当前状态快照日期:`2026-03-20`
|
|
|
|
---
|
|
|
|
## 1. 文档结论先看
|
|
|
|
### 1.1 本项目 V1 采用的核心结论
|
|
|
|
- 只支持 `碰 / 杠 / 胡 / 过`,不支持 `吃`
|
|
- 响应窗口首先只围绕“弃牌后响应”建立
|
|
- 优先级顺序采用:
|
|
- `HU > GANG > PENG > PASS`
|
|
- AI 与真人使用同一套优先级规则
|
|
- 同优先级冲突时,按出牌者之后的最近顺位优先
|
|
- `PASS` 仅表示放弃当前窗口,不等于永久放弃后续所有同类机会
|
|
- `过水不胡` 已在项目 `V1` 中启用“最小正式版”
|
|
- 玩家在响应窗口里本可 `HU` 但选择 `PASS` 后,直到自己下一次摸牌前,不能再做响应胡
|
|
- 该限制只作用于响应胡,不影响 `PENG / GANG`,也不影响自摸胡
|
|
- `一炮多响` 已在项目 `V1` 中实现,但只对 `HU` 开放多赢家同窗裁决
|
|
- `PENG / GANG` 仍保持单赢家裁决,顺位规则不变
|
|
|
|
### 1.2 为什么这样定
|
|
|
|
- 这样能和当前后端结构最自然衔接
|
|
- 可以先把响应窗口停顿、恢复和结算主链做稳
|
|
- 即使已支持一炮多响与最小版过水不胡,也仍把复杂度限制在当前统一动作入口和统一响应窗口内
|
|
|
|
这符合:
|
|
|
|
- `KISS`:一炮多响只对 `HU` 放开,多赢家共用一张牌源,避免把 `PENG / GANG` 也做成多胜出分支
|
|
- `YAGNI`:当前不抢做完整地方化 `过水不胡` 体系,也不引入可配置规则模式层
|
|
- `SOLID`:先把规则澄清文档与裁决器边界固定
|
|
- `DRY`:所有动作冲突统一走一套优先级裁决
|
|
|
|
---
|
|
|
|
## 2. 公开规则共识与本项目采用范围
|
|
|
|
### 2.1 高共识部分
|
|
|
|
结合公开资料,以下规则共识较高:
|
|
|
|
- 四川麻将 / 成都麻将常见规则中:
|
|
- 只有 `万 / 筒 / 条`
|
|
- `可碰、可杠,不可吃`
|
|
- 血战到底是一家胡后牌局不立即结束,其他未胡家继续
|
|
- 四川麻将公开资料中常见“点炮”“杠分”“查叫”“花猪”等扩展规则
|
|
- 多个公开资料都把血战到底视为成都规则或四川规则的典型变体
|
|
|
|
### 2.2 规则不完全统一的部分
|
|
|
|
公开资料中存在差异或版本不完全一致的地方:
|
|
|
|
- 是否支持 `一炮多响`
|
|
- 是否严格执行 `过水不胡`
|
|
- `过水不胡` 的解除时机
|
|
- 抢杠胡、补杠、绕杠与响应时机的细节
|
|
- 比赛规则、地方线下习惯和手游平台的实现差异
|
|
|
|
因此本项目必须明确“工程采用规则”,不能把互相矛盾的外部说法直接混进代码。
|
|
|
|
---
|
|
|
|
## 3. 本项目 V1 规则边界
|
|
|
|
### 3.1 当前先实现哪些响应窗口
|
|
|
|
`V1` 只实现:
|
|
|
|
- 某玩家打出一张牌后
|
|
- 其他仍在牌局中的玩家基于这张弃牌触发响应窗口
|
|
- 补杠声明后的抢杠胡响应窗口
|
|
|
|
`V1` 暂不实现:
|
|
|
|
- 最后一张牌必须胡的特殊强制窗口
|
|
- 多轮连续嵌套响应窗口
|
|
|
|
### 3.2 当前先支持哪些候选动作
|
|
|
|
当前候选结构已经准备支持:
|
|
|
|
- `PENG`
|
|
- `GANG`
|
|
- `HU`
|
|
- `PASS`
|
|
|
|
其中:
|
|
|
|
1. 弃牌响应窗口支持 `HU / PENG / GANG / PASS`
|
|
2. 补杠抢杠胡窗口支持 `HU / PASS`
|
|
|
|
---
|
|
|
|
## 4. 优先级规则
|
|
|
|
### 4.1 基础优先级
|
|
|
|
本项目 `V1` 的响应优先级顺序固定为:
|
|
|
|
1. `HU`
|
|
2. `GANG`
|
|
3. `PENG`
|
|
4. `PASS`
|
|
|
|
解释:
|
|
|
|
- `PASS` 不参与争夺,只表示当前窗口内放弃
|
|
- `PENG` 与 `GANG` 都是夺取弃牌控制权的动作
|
|
- `HU` 直接改变对局参与关系和结算路径,因此优先级最高
|
|
|
|
### 4.2 同优先级冲突
|
|
|
|
当多个玩家对同一张弃牌拥有同优先级动作时,`V1` 采用:
|
|
|
|
- 按出牌者之后的最近顺位优先
|
|
|
|
具体定义:
|
|
|
|
- 当前系统座位轮转顺序是 `seatNo` 递增后取模
|
|
- 因此从 `sourceSeatNo + 1` 开始,沿当前行牌方向逐个查找
|
|
- 先遇到的候选玩家优先获胜
|
|
|
|
示例:
|
|
|
|
- 4 人桌,出牌者为 `seat 0`
|
|
- `seat 1` 和 `seat 3` 同时都能 `PENG`
|
|
- 则 `seat 1` 获胜
|
|
|
|
### 4.3 为什么在 V1 只对 `HU` 支持一炮多响
|
|
|
|
这也是一个项目级工程取舍,不是宣称外部规则世界只有这一种。
|
|
|
|
原因:
|
|
|
|
- `HU` 多赢家是血战到底中较常见、且用户感知较强的规则
|
|
- 当前后端已经具备:
|
|
- 胡牌判定
|
|
- 基础结算
|
|
- 胡后继续行牌主链
|
|
- 结算历史沉淀
|
|
- 但如果把 `PENG / GANG` 也做成多赢家分支,会明显抬高后续行牌复杂度
|
|
|
|
所以 `V1` 采用:
|
|
|
|
- `HU` 可多赢家同窗裁决
|
|
- `PENG / GANG` 仍然单赢家裁决
|
|
|
|
这样做的好处是:
|
|
|
|
- 保住高价值规则一致性
|
|
- 又不破坏现有统一动作入口、统一响应窗口和统一结算出口
|
|
- 仍符合 `KISS`
|
|
|
|
---
|
|
|
|
## 5. PASS 与过手规则
|
|
|
|
### 5.1 PASS 在本项目中的定义
|
|
|
|
`PASS` 只表示:
|
|
|
|
- 当前响应窗口内
|
|
- 当前玩家放弃对当前触发牌的响应
|
|
|
|
它不表示:
|
|
|
|
- 永久放弃此类动作
|
|
- 放弃后续整局碰、杠、胡能力
|
|
|
|
### 5.2 当前窗口内的限制
|
|
|
|
在同一个响应窗口内:
|
|
|
|
- 玩家一旦提交 `PASS`
|
|
- 不能再次回到同一个窗口重新声明 `PENG / GANG / HU`
|
|
|
|
这是当前必须实现的最小一致性规则。
|
|
|
|
### 5.3 `过水不胡` 的项目处理
|
|
|
|
公开资料中可见类似“过水不胡 / 同巡振听 / 过手胡”的描述,但不同平台和地方规则细节并不完全统一。
|
|
|
|
因此本项目采取分阶段策略:
|
|
|
|
#### V1
|
|
|
|
- 不实现完整地方化 `过水不胡`
|
|
- 当前只实现“最小正式版”:
|
|
- 玩家在响应窗口里本可 `HU` 但选择 `PASS` 时,记录一次响应禁胡状态
|
|
- 在该玩家下一次真正摸牌前,后续弃牌胡与抢杠胡都不再给出 `HU` 候选
|
|
- 下一次真正摸牌后解除限制
|
|
- 不影响 `PENG / GANG`
|
|
- 不影响自摸胡
|
|
|
|
#### V2
|
|
|
|
- 评估是否加入:
|
|
- 是否仅限制同张牌
|
|
- 是否限制同一路听牌
|
|
- 是否允许加番后破除限制
|
|
- 是否需要把“解除时机”细化为摸牌、碰杠、换巡或加番后解除
|
|
|
|
---
|
|
|
|
## 6. 响应窗口生命周期
|
|
|
|
### 6.1 打开条件
|
|
|
|
当一名玩家完成弃牌后:
|
|
|
|
1. 系统生成 `TILE_DISCARDED` 公共事件
|
|
2. 系统用弃牌和当前牌桌状态构建响应候选
|
|
3. 若存在候选,则创建 `ResponseActionWindow`
|
|
4. 发出 `RESPONSE_WINDOW_OPENED` 公共事件
|
|
5. 向有资格响应的玩家分别下发私有动作消息
|
|
|
|
### 6.2 关闭条件
|
|
|
|
响应窗口在以下任一条件满足时关闭:
|
|
|
|
- 所有候选玩家都已响应
|
|
- 响应超时
|
|
- 裁决器已确定唯一胜出动作
|
|
|
|
关闭后应发出:
|
|
|
|
- `RESPONSE_WINDOW_CLOSED`
|
|
|
|
并带上至少以下信息:
|
|
|
|
- 来源座位
|
|
- 最终裁决动作类型
|
|
|
|
### 6.3 关闭后的流转
|
|
|
|
#### 若有人胜出
|
|
|
|
- 执行胜出动作
|
|
- 广播对应公共事件:
|
|
- `PENG_DECLARED`
|
|
- `GANG_DECLARED`
|
|
- `HU_DECLARED`
|
|
- `PASS_DECLARED` 一般不作为最终胜出动作事件使用
|
|
|
|
#### 若所有人都放弃
|
|
|
|
- 广播窗口关闭事件
|
|
- 继续原始出牌后的下家摸牌流程
|
|
|
|
---
|
|
|
|
## 7. 公共消息与私有消息边界
|
|
|
|
### 7.1 公共消息应该包含什么
|
|
|
|
公共事件只应表达“桌面上发生了什么”,例如:
|
|
|
|
- 某张牌被打出
|
|
- 响应窗口已打开
|
|
- 响应窗口已关闭
|
|
- 某玩家碰 / 杠 / 胡
|
|
|
|
公共事件不应广播:
|
|
|
|
- 每个玩家分别可做哪些动作
|
|
- 某玩家私下收到的教学建议
|
|
|
|
### 7.2 私有消息应该包含什么
|
|
|
|
私有动作消息应表达“你现在能做什么”,例如:
|
|
|
|
- 作用域:当前回合动作 / 响应动作
|
|
- 来源牌与来源座位
|
|
- 当前候选动作列表
|
|
- 当前窗口 ID
|
|
|
|
这也是当前后端已升级为结构化 `PrivateActionMessage` 的原因。
|
|
|
|
---
|
|
|
|
## 8. 对代码实现的直接指导
|
|
|
|
### 8.1 裁决器建议输入
|
|
|
|
后续真正实现裁决器时,建议输入至少包括:
|
|
|
|
- `ResponseActionWindow`
|
|
- 各候选玩家的最终响应
|
|
- 当前出牌座位
|
|
- 当前行牌顺序
|
|
|
|
### 8.2 裁决器建议输出
|
|
|
|
建议输出至少包括:
|
|
|
|
- 是否有人胜出
|
|
- 胜出玩家
|
|
- 胜出动作
|
|
- 窗口内已放弃玩家
|
|
- 是否继续原出牌后流转
|
|
|
|
### 8.3 当前推荐实现顺序
|
|
|
|
1. 先把 `ResponseActionWindow` 真正接入弃牌后主流程
|
|
2. 再实现窗口停顿与私有候选下发
|
|
3. 再实现优先级裁决器
|
|
4. 最后再接入 `HU` 判定与结算
|
|
|
|
不要反过来做,否则会出现:
|
|
|
|
- 胡牌判定先写了,但没有窗口停顿
|
|
- 前端已经能显示候选,但后端还无法裁决
|
|
- 公共事件和私有动作消息互相打架
|
|
|
|
---
|
|
|
|
## 9. 与当前代码进度的对应关系
|
|
|
|
当前已经完成:
|
|
|
|
- 新动作统一入口
|
|
- 新动作基础校验
|
|
- 新动作事件模型
|
|
- 响应候选模型
|
|
- 响应窗口停顿与关闭
|
|
- 基于窗口的多人响应收集
|
|
- `HU` 候选生成与胡牌判定
|
|
- `HU` 的一炮多响裁决
|
|
- 抢杠胡窗口
|
|
- 最小正式版 `过水不胡`
|
|
- 结构化私有动作消息
|
|
- H5 原型页候选消息展示占位
|
|
|
|
当前尚未完成:
|
|
|
|
- 前端正式动作面板联调
|
|
- 更完整的地方化 `过水不胡`
|
|
- 规则模式配置层
|
|
|
|
因此本文件当前的直接用途是:
|
|
|
|
- 让后续前后端联调和规则扩展有明确规则依据
|
|
- 降低“每轮新对话都重新讨论响应口径”的沟通成本
|
|
|
|
---
|
|
|
|
## 10. 本项目 V1 的最终裁决口径
|
|
|
|
为了避免歧义,本项目 `V1` 最终采用如下口径:
|
|
|
|
1. 血战到底按成都麻将大框架实现
|
|
2. 不可吃,只处理 `碰 / 杠 / 胡 / 过`
|
|
3. 当前响应窗口覆盖“弃牌后响应”与“补杠后的抢杠胡响应”
|
|
4. 优先级固定为 `HU > GANG > PENG > PASS`
|
|
5. 同优先级按出牌者之后最近顺位优先,且 `HU` 支持一炮多响
|
|
6. `PASS` 仅放弃当前窗口
|
|
7. 当前实现最小正式版 `过水不胡`,解除时机为该玩家下一次真正摸牌
|
|
8. 当前只对 `HU` 实现一炮多响,`PENG / GANG` 仍保持单赢家裁决
|
|
|
|
如果后续要改这些口径,必须先更新本文件,再改代码。
|
|
|
|
---
|
|
|
|
## 11. 参考来源与说明
|
|
|
|
以下来源用于确认“四川麻将 / 成都麻将血战到底”的高共识规则与差异点:
|
|
|
|
- [四川麻将 - 维基百科](https://zh.wikipedia.org/wiki/%E5%9B%9B%E5%B7%9D%E9%BA%BB%E5%B0%87)
|
|
- [成都麻将:血战到底 - 快懂百科](https://www.baike.com/wikiid/6198029954197195589)
|
|
- [四川麻将规则 - 同城游](https://www.tcy365.com/news/d30057.html)
|
|
- [成都麻将换三张规则 - 游戏茶苑](https://gametea.com/news/201910/9099.html)
|
|
|
|
说明:
|
|
|
|
- 上述来源之间对 `一炮多响`、`过水不胡` 等细节并不完全一致
|
|
- 因此本文中的 `V1` 规则属于“基于公开共识后的工程裁决”
|
|
- 若未来需要做更地道或更赛事化的模式,应再增加“规则模式配置层”
|