From dbfc9c8b76ae12eff3fa045762ba2f800ba4039a Mon Sep 17 00:00:00 2001 From: xiaoou Date: Sat, 4 Jul 2026 21:37:31 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=9B=BD=E6=A0=87=E8=8A=B1=E7=89=8C?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E4=B8=8D=E8=A1=A5=E7=89=8C=20+=20=E8=8A=B1?= =?UTF-8?q?=E7=89=8C=E8=A1=A5=E7=89=8C=E4=B8=8D=E9=80=92=E5=BD=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2处修复: 1. Deal(): 初始花牌替换条件扩展 - 原来仅 replace_tiles:BEFORE_GAME_START(广东)触发 - 现在 deal_cards_with_flowers action(国标)也触发 2. Deal() + StepTurn: 补花牌 → while循环替代单次if - 补来的牌也可能是花牌,需持续补直到非花牌或牌墙空 验证: 国标花牌计入得分(AI-南 +15, 花牌2张=底分3+花2×discard3) 58 tests pass, 5 variants 0 errors --- RuleEngine/MahjongRoom.cs | 45 ++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/RuleEngine/MahjongRoom.cs b/RuleEngine/MahjongRoom.cs index 2d78891..bf42f7c 100644 --- a/RuleEngine/MahjongRoom.cs +++ b/RuleEngine/MahjongRoom.cs @@ -184,7 +184,7 @@ public class MahjongRoom State.AddEvent("draw", player, drawn, $"摸牌: {MahjongTile.ToString(drawn)}"); - // Check flower + // Check flower — keep replacing until non-flower or deck empty if (MahjongTile.IsFlower(drawn)) { State.FlowerReplaced++; @@ -194,13 +194,26 @@ public class MahjongRoom State.FlowerPool[player] = new List(); State.FlowerPool[player].Add(drawn); State.Hands[player].Remove(drawn); - if (State.Deck.Count > 0) + // Keep drawing replacements until we get a non-flower + int extra = 0; + while (State.Deck.Count > 0) { - int extra = State.Deck[^1]; + extra = State.Deck[^1]; State.Deck.RemoveAt(State.Deck.Count - 1); - State.Hands[player].Add(extra); - State.AddEvent("draw", player, extra, - $"补牌: {MahjongTile.ToString(extra)}"); + if (!MahjongTile.IsFlower(extra)) + { + State.Hands[player].Add(extra); + State.AddEvent("draw", player, extra, + $"补牌: {MahjongTile.ToString(extra)}"); + break; + } + // Replacement is also a flower → add to pool, keep going + State.FlowerReplaced++; + if (!State.FlowerPool.ContainsKey(player)) + State.FlowerPool[player] = new List(); + State.FlowerPool[player].Add(extra); + State.AddEvent("flower_drawn", player, extra, + $"补花牌 {MahjongTile.ToString(extra)} → 再补"); } } } @@ -768,21 +781,26 @@ public class MahjongRoom State.IsFirstTurn = true; State.DealerOnFirstTurn = State.Dealer; - // Replace flowers in initial hands BEFORE game starts (e.g. Guangdong 鸡平胡) - if (_rules.FlowerRules != null && includeFlowers - && string.Equals(_rules.FlowerRules.ReplaceTiles, "BEFORE_GAME_START", StringComparison.OrdinalIgnoreCase)) + // Replace flowers in initial hands BEFORE game starts. + // Triggers for: Guangdong (replace_tiles: BEFORE_GAME_START), + // Guobiao (deal action: deal_cards_with_flowers), or any variant with flowers. + bool replaceInitialFlowers = _rules.FlowerRules != null && includeFlowers + && (string.Equals(_rules.FlowerRules.ReplaceTiles, "BEFORE_GAME_START", StringComparison.OrdinalIgnoreCase) + || string.Equals(_playPhase.Action, "deal_cards_with_flowers", StringComparison.OrdinalIgnoreCase)); + if (replaceInitialFlowers) { int replaced = 0; foreach (var p in State.PlayerOrder) { var hand = State.Hands[p]; - var flowers = hand.Where(MahjongTile.IsFlower).ToList(); - foreach (var f in flowers) + while (true) { - hand.Remove(f); + var flower = hand.FirstOrDefault(MahjongTile.IsFlower); + if (flower == 0) break; // no more flowers + hand.Remove(flower); if (!State.FlowerPool.ContainsKey(p)) State.FlowerPool[p] = new List(); - State.FlowerPool[p].Add(f); + State.FlowerPool[p].Add(flower); if (State.Deck.Count > 0) { int extra = State.Deck[^1]; @@ -790,6 +808,7 @@ public class MahjongRoom hand.Add(extra); replaced++; } + else break; // deck empty, stop } } if (replaced > 0)