70b00d5e6d
fix: IdentifyFans filter排除无fallback番型—防止跨变体越权
...
核心变更:
- filter从'well-known全放行'改为'只放行_fanConfig或有fallback值的'
- 排除: 断幺九/无字/缺一门/将/平胡/平和(无hardcoded fallback)
- 这些被排除时→allZeroValue→鸡胡兜底→保证非零分
效果: 南昌不再显示'断幺九+无字+平胡'等不存在于南昌规则的番型
测试: _fanConfig补全16个番型, 58 tests pass
2026-07-05 01:09:42 +08:00
c2b5136085
refactor: _wildcards static→实例级 WildcardRegistry
...
Root cause: static HashSet跨测试/跨变体污染+硬编码名→编码映射
Changes:
- WildcardRegistry: 实例级wildcard管理(IsWildcard/CountWildcards/Clone)
- GameState: 新增Wildcards属性(含Clone)
- MahjongTile: 移除static_wildcards,IsWildcard仅查编码50-59
+ToString(tile,wildcards)重载用于游戏上下文显示
- MeldsSolver: _wildcards字段→构造函数注入(WildcardRegistry?)
- PhaseMachine: _wildcards字段+构造注入
- Deal(): State.Wildcards.Clear()+AddRange替代static ConfigureWildcards
+NameToEncoding查表替代switch硬编码
- RandomMahjongAI/HumanMahjongPlayer: state.Wildcards替代static调用
- HumanMahjongPlayer.CheckTing: 补wildcardCount参数(之前遗漏)
- ExecuteWinClaim: IsFinished=true→Settle()(之前Phase漏设)
Test: CoreTests清理ConfigureWildcards()→WildcardRegistry测试
Impact: 零static state→不同变体/测试完全隔离,未来支持随机宝牌
2026-07-04 20:05:26 +08:00
e39c9ab4f1
fix: 根除flaky测试层三bug
...
Root cause chain (逐层发现):
1. 非庄家第一轮: 南碰了自己的弃牌→不摸牌→Deck.Count=55≠54
→ 修复: 测试接受54|55两情况
2. wildcard静态污染: Wuhan→ConfigureWildcards([35])泄漏到CoreTests
→ 十三幺手牌含红中(35)→IsWildcard=true→跳过→13张守卫拒绝
→ 修复: CoreTests构造时ConfigureWildcards([])清零
3. Random.Shared非确定性: 牌库洗牌用共享Random→跨run不可复现
→ 修复: MahjongRoom(seed:)参数→测试seed:42确定性
附加:
- AssemblyInfo.cs: 关闭xUnit并行(静态状态竞态)
- 补'碰碰和'到FanValue fallback switch(国标名称)
Test: 20/20 all green, first time since project creation
2026-07-04 19:30:21 +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
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