Commit Graph

19 Commits

Author SHA1 Message Date
21bf35c453 fix: DSL命名不一致 — camelCase→underscore_case (UnderscoredNamingConvention)
DSL YAML字段includeHonors/includeFlowers/wildcardCount等使用了camelCase,
但DslLoader配置了UnderscoredNamingConvention(期望include_honors)。
导致所有DSL的deck配置(字牌/花牌/wildcard)从未生效:
- 武汉: 108张(只有数牌) → 现140张(136+4wildcard)
- 国标: 108张 → 现144张(+花+字)
- 广东: 108张 → 现136张(+花+字)

修复: 4个YAML文件统一改为underscore_case
2026-07-04 17:33:42 +08:00
bf041b7e50 fix: CheckWin守卫!=14拒绝副露后手牌 + FullHand合并副露
根因: CheckWin要求tiles.Count==14,碰/杠后手牌只有11/8/5/2张
修复:
- CheckWin守卫: !=14 → total%3!=2 (接受2,5,8,11,14)
- FullHand(): 合并手牌+Exposed副露→虚拟完整手牌
- 所有CheckWin调用点改用FullHand (MahjongRoom+PhaseMachine+HumanMahjongPlayer)
- 新增集成测试: 副露后11张手牌自摸
2026-07-04 17:31:31 +08:00
d416450e56 fix: CanAnKong硬编码false + 人类HUD显示听牌/杠/对手状态
修复:
- CanAnKong: 硬编码false → 检查手牌中4张相同(暗杠)
- HumanMahjongPlayer: 添加MeldsSolver依赖,实时检测听牌
- 人类HUD: 显示牌墙/副露/听牌🀄/杠类型(暗/明/加)
- 交互模式人类: 对手显示'X张手牌 | 已pung[..]'不暴露手牌
2026-07-04 17:24:05 +08:00
3c381f2758 feat: 人类玩家吃碰杠胡 — HandleDiscardReactions暂停询问
- HandleDiscardReactions重写: 按座位顺序逐个询问
- 人类玩家在可反应列表中时暂停(h=胡/p=碰/k=杠/Enter=过)
- AI玩家自动决策(先胡后碰杠)
- ExecuteWinClaim/ExecutePungKong抽取公共逻辑
- 碰/杠后让人类选择出哪张牌
2026-07-04 11:52:15 +08:00
f9242cf965 fix: 人类玩家显示摸到的牌 (LastDrawnTile + 箭头高亮)
- GameState新增LastDrawnTile字段
- StepTurn摸牌时记录LastDrawnTile
- HumanMahjongPlayer显示'刚刚摸到:X'并用→←箭头标记新牌
- 庄家首轮LastDrawnTile清空
2026-07-04 11:49:31 +08:00
4302ec2fd5 feat: 集成测试 + 手动出牌模式 + discart pool幽灵牌修复
集成测试 (10个):
- 发牌: 庄14闲13, 牌墙55
- 回合流转: 庄家第一轮不摸牌, 非庄家摸牌后出牌
- 数据完整性: 10回合后手牌+副露+牌墙+弃牌=108
- 对局完整性: 4种DSL全部不出错完成
- 构造听牌: 完整手牌第一轮自摸

手动出牌 (--human):
- HumanMahjongPlayer: 显示手牌/可选操作/h=胡/p=碰/k=杠/1-N=出牌
- MahjongRoom: humanPlayer参数

修复: DiscardPool碰/胡后不移除→幽灵牌→总牌数溢出
2026-07-04 11:45:54 +08:00
bb43ed7c89 fix: CheckWin缺少wildcard/258参数导致武汉麻将0%胡牌 + 庄家第一轮跳过摸牌
Root cause 1: 所有CheckWin调用未传wildcardCount/require258Pair
- StepTurn自摸: 5处遗漏 → 癞子在手牌中被当废牌
- HandleDiscardReactions: 2处遗漏
- PhaseMachine: 2处遗漏
→ 武汉麻将永远不能胡牌

Root cause 2: 庄家开局14张+摸牌=15张, CheckWin守卫≠14拒绝
→ 庄家永远不能自摸 → 修复: 庄家第一轮跳过摸牌

额外修复:
- RandomMahjongAI: 永远不出癞子(预留wildcard)
- ScoreEngine.FanValue: 从DSL _fanConfig读取番值
- HandleDiscardReactions: 同优先级座位顺序
- 新增GetWinParams/CountWildcardsInHand辅助方法

验证: 47/47测试, Wuhan 1.6%胡牌(500局), Sichuan 0.4%
2026-07-04 11:39:00 +08:00
55447d6b05 fix: Code Review — CheckTing完全断裂 + 座位顺序 + FanValue硬编码
🔴 Critical: CheckTing逻辑完全错误
- 旧: testHand.RemoveAt(i) → 13张 → CheckWin守卫拒绝(≠14) → 听牌检测永远false
- 新: 遍历所有可摸牌(27-34种), CheckWin(hand, newTile:tile) → 正确检测听牌
- 新增2个听牌测试

🟡 Medium: HandleDiscardReactions 同优先级顺序
- 旧: OrderByDescending取第一个,不保证座位顺序
- 新: 按座位顺序遍历,高优先级覆盖,同优先级先到先得

🟡 Medium: ScoreEngine.FanValue 硬编码番值
- 旧: switch expression 仅5种番型
- 新: 优先从 _fanConfig(DSL)读取,fallback到硬编码

🟢 Low: 删除硬编码的258将事件(非武汉也输出)
2026-07-04 11:33:13 +08:00
c902482d4b fix: StepTurn回合流转重构 + 碰/杠牌数修正
Root cause:
1. 摸牌在碰/杠检测之前→摸的牌浪费→手牌净减
2. RemoveAll一次删光所有同牌→碰2张变删N张
3. 碰/杠后没让玩家出牌→手牌只减不补
4. 显示只展示手牌不展示暴露副露

修复:
- 重构StepTurn: 先处理LastDiscard反应(碰/杠/胡)
  没人反应才摸牌→决定→出牌
- RemoveAll→Remove 精准删除
- 碰/杠后强制出一张牌
- HandleDiscardReactions替代旧CheckReactions
- RenderFinal展示Exposed副露
2026-07-04 11:29:49 +08:00
b871395884 fix: 交互模式逐回合展示 + Deal()公开 + 发牌输出修正
问题:
1. 交互模式 Run() 直接跑完整局,只渲染最终状态
2. RenderGame 手牌.OrderBy()排序,洗牌后仍显顺序
3. 牌墙剩余显示0因为游戏已跑完

修复:
- 交互模式: room.Deal()→RenderDeal→逐回合StepTurn+ReadLine
- 发牌输出: 显示每人张数 + 牌墙剩余,不排序手牌
- 每回合: 显示事件(摸/打/碰/杠/胡) + 当前手牌
- Run()保留用于自动模式
2026-07-04 11:22:46 +08:00
504189a918 build: 升级 net9.0 → net10.0 (服务端 SDK 已升级至 10.0.109) 2026-07-04 10:58:12 +08:00
68e2f51632 build: 添加 RollForward Major 兼容 .NET 10 runtime (目标保持 net9.0) 2026-07-04 10:54:51 +08:00
45a1036cbd build: 升级 target framework net9.0 → net10.0 (适配 macOS .NET 10 runtime) 2026-07-04 10:53:41 +08:00
ea4388ee3e docs: macOS 编译部署运行完整指南 2026-07-04 10:49:13 +08:00
ffe90b6d3d feat: 番型识别DSL驱动化 + 全不靠/一色双龙会测试完善
IdentifyFans: 从4种扩展到17种结构性番型自动识别
- 清一色/混一色/字一色/对对胡/暗七对/带幺九/混幺九
- 缺一门/平胡/断幺九/全大/全中/全小/大于五/小于五/全双/碰碰和
- FanConfig 新增 Condition 字段预留game-event条件

TryAllOrphans: 修正容差 +2(16选14),允许非幺九数牌
TryDoubleDragon: 增加honor/越界保护

测试: 33→45,新增12个(全不靠×3/一色双龙会×2/番型×7)
100局压测: 0出错
2026-07-04 10:46:09 +08:00
96246d2fec [verified] reinstate Fact attribute on 全不靠 test 2026-07-03 18:02:32 +08:00
afce77cca4 [verified] review fixes: priority arbitration, wildcard config, dead code
- CheckReactions: collect all claims, pick highest priority (win>kong>pung>chi)
- Deal(): read wildcardCount from DSL config instead of hardcoded 4
- CheckTing(): propagate wildcardCount + require258Pair to CheckWin
- ThirteenOrphans: fix neededForPair formula (extra>0?0:1)
- Remove FanConfig.Get() dead code
- Fill empty 全不靠 test body
2026-07-03 18:02:13 +08:00
1346733996 [verified] fix: wildcard count correction in CheckWin tile count check
根因: CheckWin 开头 tiles.Count != 14 检查未计入 wildcardCount,
导致 12 tiles + 2 wildcards = 14 被误判为手牌不足。

修复: tiles.Count + wildcardCount != 14
同步修正鬼牌_1wildcard补刻子测试用13 tiles + 1 wildcard = 14

测试: 33/33 全部通过
2026-07-03 17:57:16 +08:00
3c6748bf06 [verified] feat: 麻将规则引擎 Demo 完整实现
RuleEngine 核心类:
- MahjongTile.cs — int编码 (1-29万条筒, 31-37字, 41-48花, 50-59宝牌)
- MeldsSolver.cs — 标准回溯 + wildcard缺口填充 + 七对/十三幺/全不靠
- PhaseMachine.cs — 回合机(摸打碰杠胡 + 优先级仲裁)
- ScoreEngine.cs — 番型计分 + 互斥图
- DslLoader.cs — YAML DSL加载 + 能力检查

4个DSL: 四川血战/广东鸡平胡/国标麻将/武汉麻将
控制台Demo: 交互模式 + 自动模式(--auto)
测试: 33个测试用例, 32个通过
2026-07-03 17:51:59 +08:00