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将事件(非武汉也输出)
This commit is contained in:
xiaoou
2026-07-04 11:33:13 +08:00
parent c902482d4b
commit 55447d6b05
3 changed files with 87 additions and 28 deletions

View File

@ -349,4 +349,36 @@ public class MeldsSolverTests
var fans = _solver.IdentifyFans(result!);
Assert.Contains("断幺九", fans);
}
// === 听牌检查 ===
[Fact]
public void _缺一张__ShouldDetectTing()
{
// 13 tiles, needs 9万 to complete 123万 456万 789万 111条 99条
var hand = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 11, 11, 11, 19, 19 };
var allTiles = MahjongTile.AllTiles(false, false);
bool hasTing = false;
foreach (var tile in allTiles)
{
if (hand.Count(t => t == tile) >= 4) continue;
var r = _solver.CheckWin(hand, newTile: tile);
if (r != null && r.IsWin) { hasTing = true; break; }
}
Assert.True(hasTing, "13张听牌应检测到至少一张能胡的牌");
}
[Fact]
public void _乱牌__ShouldNotDetectTing()
{
var hand = new List<int> { 1, 3, 5, 7, 9, 11, 13, 15, 21, 23, 25, 31, 33 };
var allTiles = MahjongTile.AllTiles(false, false);
bool hasTing = false;
foreach (var tile in allTiles)
{
if (hand.Count(t => t == tile) >= 4) continue;
var r = _solver.CheckWin(hand, newTile: tile);
if (r != null && r.IsWin) { hasTing = true; break; }
}
Assert.False(hasTing, "乱牌不应检测到听牌");
}
}