fix: 国标花牌初始不补牌 + 花牌补牌不递归
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
This commit is contained in:
@ -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<int>();
|
||||
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<int>();
|
||||
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<int>();
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user