Files
card-game-engine/RuleEngine/Core/Deck.cs
xiaoou 1576253caa fix: 子代理审查26问题修复13个(剩余为编码定义/DSL文档字段)
本次修复(13/26):
- FuFlag传播: PhaseConfig加FuFlag属性+BuildPhases映射
- Excludes/Conflicts引用完整性: 引用的番型名必须存在于fan_types
- WildcardBase常量提取: WildcardRegistry引用MahjongTile.WildcardBase
- 合规验证扩展: max_fan/phase.type/end_condition/action/priority
- FanCalculationPolicy未消费警告

不修复的剩余13个:
- 编码常量(MahjongTile domain定义,非配置项)
- DSL字段仅文档(POCO有但引擎硬编码等效逻辑)
- LOW代码卫生项

--check输出现在会报告: excludes/conflicts引用了不存在的番型(如国标15个)
2026-07-04 23:11:29 +08:00

55 lines
1.9 KiB
C#

namespace RuleEngine.Core;
public class MahjongDeck
{
public List<int> Tiles { get; private set; } = new();
public MahjongDeck(bool includeHonors = false, bool includeFlowers = false, int wildcardCount = 0,
int? expectedTotal = null, int wildcardBase = 50) // default matches MahjongTile.WildcardBase
{
var allTiles = MahjongTile.AllTiles(includeHonors, includeFlowers, wildcardCount);
foreach (var t in allTiles)
{
int count = MahjongTile.IsFlower(t) ? 1 : 4;
// Skip extra encoding wildcards (they're added separately below)
if (t >= wildcardBase) continue;
for (int i = 0; i < count; i++)
Tiles.Add(t);
}
// Add extra wildcard tiles
for (int i = 0; i < wildcardCount; i++)
Tiles.Add(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)
{
rng ??= Random.Shared;
int n = Tiles.Count;
while (n > 1)
{
int k = rng.Next(n--);
(Tiles[n], Tiles[k]) = (Tiles[k], Tiles[n]);
}
}
public int Draw()
{
if (Tiles.Count == 0)
throw new InvalidOperationException("Deck is empty");
int last = Tiles[^1];
Tiles.RemoveAt(Tiles.Count - 1);
return last;
}
public int Count => Tiles.Count;
}