From 359e02886fad46abeddf5129e10a48604ffd0e03 Mon Sep 17 00:00:00 2001 From: xiaoou Date: Sat, 4 Jul 2026 22:13:53 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20--check=E8=BE=93=E5=87=BA=E5=8C=BA?= =?UTF-8?q?=E5=88=86=E8=83=BD=E5=8A=9B=E6=B3=A8=E5=86=8C=20vs=20=E8=A7=84?= =?UTF-8?q?=E5=88=99=E8=A6=86=E7=9B=96,=20=E4=B8=8D=E5=86=8D=E8=AF=AF?= =?UTF-8?q?=E5=AF=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ValidateRuleCompliance 新增3项检查: - 鸡胡缺失警告 (fan_types 应配鸡胡兜底) - base_fan=0 番型警告 (标记番型需更高番型覆盖) - 番型识别率统计 (DSL中有多少引擎能识别) 输出变更: - 'DSL适配率' → '能力注册' (准确描述含义) - 新增 '规则合规检查通过' (warnings=0时显示) - --check末尾加警告: 能力注册≠完整规则覆盖 --- Demo/Program.cs | 12 ++++++++---- RuleEngine/Dsl/DslLoader.cs | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Demo/Program.cs b/Demo/Program.cs index 4f0bfa6..fe3e5f6 100644 --- a/Demo/Program.cs +++ b/Demo/Program.cs @@ -40,15 +40,19 @@ try rules = loader.Load(dslPath); var (r, m, pct) = caps.ComputeCoverage(rules.Requires); string status = pct == 100 ? "✅" : "⚠"; - Console.WriteLine($"{status} DSL 适配率: {m}/{r} ({pct}%) — {rules.Game.Name}"); + Console.WriteLine($"{status} 能力注册: {m}/{r} ({pct}%) — {rules.Game.Name}"); // Rule-level compliance check (finer granularity than capability check) var warnings = caps.ValidateRuleCompliance(rules); if (warnings.Count > 0) { - Console.WriteLine($" ⚠ {warnings.Count} 条规则引擎无法完全执行:"); + Console.WriteLine($" ⚠ {warnings.Count} 条规则警告:"); foreach (var w in warnings) - Console.WriteLine($" • {w}"); + Console.WriteLine($"{w}"); + } + else + { + Console.WriteLine($" ✅ 规则合规检查通过"); } if (pct < 100) @@ -67,7 +71,7 @@ catch (Exception ex) if (checkOnly) { - Console.WriteLine($"✅ 仅验证模式 — 未运行牌局"); + Console.WriteLine($"\n✅ 仅验证模式 — 未运行牌局\n 注意: 能力注册≠完整规则覆盖, 需逐条验证玩法规则"); return 0; } diff --git a/RuleEngine/Dsl/DslLoader.cs b/RuleEngine/Dsl/DslLoader.cs index 385807c..ffcd287 100644 --- a/RuleEngine/Dsl/DslLoader.cs +++ b/RuleEngine/Dsl/DslLoader.cs @@ -113,6 +113,20 @@ public class CapabilityRegistry if (rules.Scoring.Mode != "fan_table") warnings.Add($"scoring.mode={rules.Scoring.Mode} 引擎仅支持fan_table→忽略"); + // 鸡胡 兜底番型: DSL应配置以避免FanValue=0 + if (!rules.FanTypes.Any(f => f.Name == "鸡胡")) + warnings.Add("fan_types 缺少鸡胡兜底番型→建议添加 { name: 鸡胡, base_fan: 1 }"); + + // 番型值检查: base_fan=0 的标记番型需有更高番型覆盖 + var zeroFans = rules.FanTypes.Where(f => f.BaseFan <= 0).ToList(); + if (zeroFans.Count > 0) + warnings.Add($"有 {zeroFans.Count} 个番型 base_fan=0 ({string.Join(", ", zeroFans.Select(f => f.Name))})→仅当被更高番型排除时有用"); + + // 番型识别率: DSL 中多少番型引擎能识别 + int recognized = rules.FanTypes.Count(f => enginePatterns.Contains(f.Name)); + if (recognized < rules.FanTypes.Count) + warnings.Add($"番型识别率: {recognized}/{rules.FanTypes.Count}→{rules.FanTypes.Count - recognized} 个番型得分为0"); + return warnings; } }