fix: 番型互斥从未应用 + FanValue兜底乱给分 + 白名单过滤

Root cause:
1. ApplyFanExclusions定义但从未被调用 → 互斥(清一色⊃缺一门)形同虚设
2. FanValue中 _=>1 兜底 → '缺一门''平胡'等不在DSL的番型也被+1分
3. IdentifyFans返回所有结构模式 → 与DSL配置不一致

修复:
- CheckWin五处IdentifyFans调用后加ApplyFanExclusions
- FanValue去掉_=>1,改为只认DSL配置+硬编码知名番型
- IdentifyFans末尾白名单过滤:只返回DSL或知名番型
- PhaseMachine.GetFanValue同步更新
- ScoreEngine: 不在DSL的番型→0分
This commit is contained in:
xiaoou
2026-07-04 18:12:06 +08:00
parent 87df914c8d
commit a06f40bd2d
3 changed files with 19 additions and 16 deletions

View File

@ -43,7 +43,7 @@ public class MeldsSolver
var sevenPairs = TrySevenPairs(tiles, wildcardCount); var sevenPairs = TrySevenPairs(tiles, wildcardCount);
if (sevenPairs != null) if (sevenPairs != null)
{ {
sevenPairs.Fans = IdentifyFans(sevenPairs); sevenPairs.Fans = ApplyFanExclusions(IdentifyFans(sevenPairs));
return sevenPairs; return sevenPairs;
} }
@ -51,7 +51,7 @@ public class MeldsSolver
var thirteen = TryThirteenOrphans(tiles, wildcardCount); var thirteen = TryThirteenOrphans(tiles, wildcardCount);
if (thirteen != null) if (thirteen != null)
{ {
thirteen.Fans = IdentifyFans(thirteen); thirteen.Fans = ApplyFanExclusions(IdentifyFans(thirteen));
return thirteen; return thirteen;
} }
@ -59,7 +59,7 @@ public class MeldsSolver
var allOrphans = TryAllOrphans(tiles, wildcardCount); var allOrphans = TryAllOrphans(tiles, wildcardCount);
if (allOrphans != null) if (allOrphans != null)
{ {
allOrphans.Fans = IdentifyFans(allOrphans); allOrphans.Fans = ApplyFanExclusions(IdentifyFans(allOrphans));
return allOrphans; return allOrphans;
} }
@ -67,7 +67,7 @@ public class MeldsSolver
var doubleDragon = TryDoubleDragon(tiles, wildcardCount); var doubleDragon = TryDoubleDragon(tiles, wildcardCount);
if (doubleDragon != null) if (doubleDragon != null)
{ {
doubleDragon.Fans = IdentifyFans(doubleDragon); doubleDragon.Fans = ApplyFanExclusions(IdentifyFans(doubleDragon));
return doubleDragon; return doubleDragon;
} }
@ -82,7 +82,7 @@ public class MeldsSolver
if (!IsValid258Pair(result.PairTiles[0], result.PairTiles[1])) if (!IsValid258Pair(result.PairTiles[0], result.PairTiles[1]))
return new MeldsResult { IsWin = false }; return new MeldsResult { IsWin = false };
} }
result.Fans = IdentifyFans(result); result.Fans = ApplyFanExclusions(IdentifyFans(result));
return result; return result;
} }
@ -662,7 +662,11 @@ public class MeldsSolver
if (melds.Count > 0 && melds.All(m => m.Type == "kezi") && !fans.Contains("对对胡")) if (melds.Count > 0 && melds.All(m => m.Type == "kezi") && !fans.Contains("对对胡"))
fans.Add("碰碰和"); fans.Add("碰碰和");
return fans; // Filter: only keep fans that exist in DSL config or are well-known
return fans.Where(f => _fanConfig.ContainsKey(f) ||
f is "清一色" or "混一色" or "对对胡" or "碰碰和" or "暗七对" or "七对"
or "带幺九" or "十三幺" or "字一色" or "断幺九"
or "缺一门" or "平胡" or "全大" or "全中" or "全小" or "全双").ToList();
} }
// === 番型互斥应用 === // === 番型互斥应用 ===

View File

@ -102,14 +102,11 @@ public class MahjongPhaseMachine
private int GetFanValue(string fanName) private int GetFanValue(string fanName)
{ {
// Simple lookup — full implementation would read from DSL
return fanName switch return fanName switch
{ {
"清一色" => 4, "清一色" => 24, "混一色" => 6, "对对胡" => 2,
"对对胡" => 2, "暗七对" => 8, "七对" => 8, "带幺九" => 2, "十三幺" => 88,
"暗七对" => 4, _ => 0
"带幺九" => 2,
_ => 1
}; };
} }

View File

@ -84,15 +84,17 @@ public class MahjongScoreEngine
{ {
if (_fanConfig.TryGetValue(fan, out var def)) if (_fanConfig.TryGetValue(fan, out var def))
return def.BaseFan; return def.BaseFan;
// Fallback for fan names not in config // Hardcoded values for well-known fans not in every DSL
return fan switch return fan switch
{ {
"清一色" => 4, "清一色" => 24,
"混一色" => 6,
"对对胡" => 2, "对对胡" => 2,
"暗七对" => 4, "暗七对" => 8,
"七对" => 8,
"带幺九" => 2, "带幺九" => 2,
"十三幺" => 88, "十三幺" => 88,
_ => 1 _ => 0
}; };
} }
} }