diff --git a/RuleEngine/Core/Deck.cs b/RuleEngine/Core/Deck.cs index 4e5a3f2..5f183b1 100644 --- a/RuleEngine/Core/Deck.cs +++ b/RuleEngine/Core/Deck.cs @@ -4,7 +4,7 @@ public class MahjongDeck { public List Tiles { get; private set; } = new(); - public MahjongDeck(bool includeHonors = false, bool includeFlowers = false, int wildcardCount = 0) + public MahjongDeck(bool includeHonors = false, bool includeFlowers = false, int wildcardCount = 0, int? expectedTotal = null) { var allTiles = MahjongTile.AllTiles(includeHonors, includeFlowers, wildcardCount); foreach (var t in allTiles) @@ -19,6 +19,15 @@ public class MahjongDeck // Add extra wildcard tiles for (int i = 0; i < wildcardCount; i++) Tiles.Add(MahjongTile.WildcardBase + i); + + // Validate against DSL total if specified + if (expectedTotal.HasValue && Tiles.Count != expectedTotal.Value) + { + throw new InvalidOperationException( + $"牌库大小不匹配: 引擎生成 {Tiles.Count} 张, DSL 声明 {expectedTotal.Value} 张。" + + $" includeHonors={includeHonors} includeFlowers={includeFlowers} wildcardCount={wildcardCount}." + + $" 请检查 DSL deck.total 字段与 include_honors/include_flowers 的一致性。"); + } } public void Shuffle(Random? rng = null) diff --git a/RuleEngine/MahjongRoom.cs b/RuleEngine/MahjongRoom.cs index 8f2429e..e051252 100644 --- a/RuleEngine/MahjongRoom.cs +++ b/RuleEngine/MahjongRoom.cs @@ -685,7 +685,8 @@ public class MahjongRoom } } - var deck = new MahjongDeck(includeHonors, includeFlowers, wildcardCount); + var deck = new MahjongDeck(includeHonors, includeFlowers, wildcardCount, + expectedTotal: _rules.Deck.Total); deck.Shuffle(_rng); State.Deck = deck.Tiles; diff --git a/dsl-examples/guangdong_jipinghu.yaml b/dsl-examples/guangdong_jipinghu.yaml index ac303a8..df041d0 100644 --- a/dsl-examples/guangdong_jipinghu.yaml +++ b/dsl-examples/guangdong_jipinghu.yaml @@ -17,7 +17,7 @@ deck: generator: mahjong include_honors: true include_flowers: true - total: 136 + total: 144 deal: cards_per_player: 13