From 4e9f06d5cda3c4bca8e039f99fc0b765dba95e0c Mon Sep 17 00:00:00 2001 From: xiaoou Date: Sat, 4 Jul 2026 21:46:58 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20PhaseMachine=E7=A1=AC=E7=BC=96=E7=A0=81>?= =?UTF-8?q?=3D8=E7=95=AA=20=E2=86=92=20=E8=AF=BBDSL=20win=5Fmin=5Ffan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 4处修复: - PhaseMachine构造函数新增 _winMinFan 参数 - GetLegalActions 中 discard win check (line 139): >= 8 → >= _winMinFan - GetLegalActions 中 self-draw win check (line 165): >= 8 → >= _winMinFan - CheckCondition 中的 can_win*_and_fan_ge_8 (line 97-98): >= 8 → >= _winMinFan - MahjongRoom 传参: winMinFan=_rules.WinMinFan 效果: 国标胡牌率 30%→13% (baseFan<8的低番手牌被正确拦截) 58 tests pass, 5 variants 0 errors --- RuleEngine/MahjongRoom.cs | 3 ++- RuleEngine/Phase/PhaseMachine.cs | 13 ++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/RuleEngine/MahjongRoom.cs b/RuleEngine/MahjongRoom.cs index bf42f7c..7638956 100644 --- a/RuleEngine/MahjongRoom.cs +++ b/RuleEngine/MahjongRoom.cs @@ -40,7 +40,8 @@ public class MahjongRoom _phaseMachine = new MahjongPhaseMachine(phases, _solver, wildcardCount: wc, require258: r258, fanConfig: fanConfig, jiHuSelfDrawOnly: _rules.WinRule?.JiHuSelfDrawOnly ?? false, - wildcards: State.Wildcards); + wildcards: State.Wildcards, + winMinFan: _rules.WinMinFan); _scoreEngine = new MahjongScoreEngine(new ScoringConfig { diff --git a/RuleEngine/Phase/PhaseMachine.cs b/RuleEngine/Phase/PhaseMachine.cs index 38a6083..82f8636 100644 --- a/RuleEngine/Phase/PhaseMachine.cs +++ b/RuleEngine/Phase/PhaseMachine.cs @@ -44,13 +44,15 @@ public class MahjongPhaseMachine private readonly bool _jiHuSelfDrawOnly; private readonly WildcardRegistry _wildcards; private readonly bool _chiAllowed; + private readonly int _winMinFan; public bool ChiAllowed => _chiAllowed; public MahjongPhaseMachine(List phases, MeldsSolver solver, int wildcardCount = 0, bool require258 = false, Dictionary? fanConfig = null, bool jiHuSelfDrawOnly = false, - WildcardRegistry? wildcards = null) + WildcardRegistry? wildcards = null, + int winMinFan = 0) { _phases = phases; _solver = solver; @@ -59,6 +61,7 @@ public class MahjongPhaseMachine _fanConfig = fanConfig ?? new(); _jiHuSelfDrawOnly = jiHuSelfDrawOnly; _wildcards = wildcards ?? new(); + _winMinFan = winMinFan; _chiAllowed = phases.Any(p => p.OthersReactions.Any(o => o.Action == "chi")); } @@ -94,8 +97,8 @@ public class MahjongPhaseMachine "can_chi" => chiAllowed, "can_win" => canSelfWin, "can_win_tumo" => canSelfWin, - "can_win_tumo_and_fan_ge_8" => canSelfWin && fanSum >= 8, - "can_win_and_fan_ge_8" => canSelfWin && fanSum >= 8, + "can_win_tumo_and_fan_ge_8" => canSelfWin && fanSum >= _winMinFan, + "can_win_and_fan_ge_8" => canSelfWin && fanSum >= _winMinFan, _ => true // unknown condition → allow (fail-open for safety) }; } @@ -136,7 +139,7 @@ public class MahjongPhaseMachine { // Don't add win action; 鸡胡 can only self-draw } - else if (!requireWinFan || result.Fans.Sum(f => GetFanValue(f)) >= 8) + else if (!requireWinFan || result.Fans.Sum(f => GetFanValue(f)) >= _winMinFan) actions.Add(new ActionOption { Action = "win", Priority = 4 }); } } @@ -162,7 +165,7 @@ public class MahjongPhaseMachine wildcardCount: wildInSelf, require258Pair: _require258); if (tumoResult != null && tumoResult.IsWin) { - if (!requireWinFan || tumoResult.Fans.Sum(f => GetFanValue(f)) >= 8) + if (!requireWinFan || tumoResult.Fans.Sum(f => GetFanValue(f)) >= _winMinFan) actions.Add(new ActionOption { Action = "win", Priority = 4 }); } }