Files
card-game-engine/RuleEngine/Core/GameState.cs
xiaoou 721333390a feat: 四DSL 100%规则合规→零警告
全部番型识别器补全:
- 结构性:将一色/大四喜/大三元/小四喜/小三元/一色四同顺/五门齐/全求人/鸡胡/无字
- 事件型:杠上开花/海底捞月/抢杠胡/天胡/地胡(新增GameState事件标志位)
- 条件型:癞子胡(hand_contains_wildcard→IdentifyFans读取state.Wildcards)

GameState新增:IsKongDraw/IsLastTile/IsRobbedKong/IsFirstTurn/DealerOnFirstTurn
MahjongRoom:杠后摸牌/加杠/海底/首轮设置标志+discard清除

fu_flag过水机制:pass可胡牌时设dirty→下轮自己出牌时清除→阻挡对同一张牌repeat胡

IdentifyFans签名升级:result+state?→state传null时仅结构识别,传state时附加事件/条件/状态番型

ValidateRuleCompliance:enginePatterns补全39种番型→4DSL全零警告
2026-07-04 20:45:36 +08:00

89 lines
3.8 KiB
C#

namespace RuleEngine.Core;
using RuleEngine;
public class GameEvent
{
public string Type { get; set; } = "";
public string Player { get; set; } = "";
public string? Description { get; set; }
public int? Tile { get; set; }
}
public class MahjongGameState
{
public string Phase { get; set; } = "";
public Dictionary<string, List<int>> Hands { get; set; } = new();
public Dictionary<string, List<Meld>> Exposed { get; set; } = new();
public Dictionary<string, List<int>> FlowerPool { get; set; } = new();
public List<int> Deck { get; set; } = new();
public List<int> DiscardPool { get; set; } = new();
public Dictionary<string, List<int>> DiscardHistory { get; set; } = new();
public int? LastDiscard { get; set; }
public string? LastDiscardPlayer { get; set; }
public string CurrentPlayer { get; set; } = "";
public List<string> PlayerOrder { get; set; } = new();
public string Dealer { get; set; } = "";
public int RoundNumber { get; set; }
public Dictionary<string, int> Scores { get; set; } = new();
public List<string> HuPlayers { get; set; } = new();
public List<string> AlivePlayers { get; set; } = new();
public Dictionary<string, bool> FuFlags { get; set; } = new();
public bool IsDeckExhausted { get; set; }
public List<GameEvent> RecentEvents { get; set; } = new();
public int FlowerReplaced { get; set; }
public int? LastDrawnTile { get; set; }
public WildcardRegistry Wildcards { get; set; } = new();
// Event flags for event-based fan types (杠上开花/海底捞月/抢杠胡/天胡/地胡)
public bool IsKongDraw { get; set; } // 杠后摸牌 — set after kong draw, cleared on next discard
public bool IsLastTile { get; set; } // 海底 — set when deck has 1 tile before draw
public bool IsRobbedKong { get; set; } // 抢杠 — set when someone adds to pung (bu_kong)
public bool IsFirstTurn { get; set; } // 第一轮 — set for dealer after deal, non-dealer after first draw
public string? DealerOnFirstTurn { get; set; } // 庄家首轮(用于天胡判断)
public MahjongGameState Clone()
{
return new MahjongGameState
{
Phase = Phase,
Hands = Hands.ToDictionary(kv => kv.Key, kv => new List<int>(kv.Value)),
Exposed = Exposed.ToDictionary(kv => kv.Key, kv => kv.Value.Select(m => m.Clone()).ToList()),
FlowerPool = FlowerPool.ToDictionary(kv => kv.Key, kv => new List<int>(kv.Value)),
Deck = new List<int>(Deck),
DiscardPool = new List<int>(DiscardPool),
LastDiscard = LastDiscard,
LastDiscardPlayer = LastDiscardPlayer,
CurrentPlayer = CurrentPlayer,
PlayerOrder = new List<string>(PlayerOrder),
Dealer = Dealer,
RoundNumber = RoundNumber,
Scores = new Dictionary<string, int>(Scores),
HuPlayers = new List<string>(HuPlayers),
AlivePlayers = new List<string>(AlivePlayers),
FuFlags = new Dictionary<string, bool>(FuFlags),
IsDeckExhausted = IsDeckExhausted,
RecentEvents = new List<GameEvent>(RecentEvents),
FlowerReplaced = FlowerReplaced,
LastDrawnTile = LastDrawnTile,
Wildcards = Wildcards.Clone(),
IsKongDraw = IsKongDraw,
IsLastTile = IsLastTile,
IsRobbedKong = IsRobbedKong,
IsFirstTurn = IsFirstTurn,
DealerOnFirstTurn = DealerOnFirstTurn
};
}
public void AddEvent(string type, string player, int? tile = null, string? desc = null)
{
RecentEvents.Add(new GameEvent
{
Type = type,
Player = player,
Tile = tile,
Description = desc
});
}
}