fix: flower_rules DSL字段全部接入引擎(花牌计分+开局换花)

Root cause: flower_rules.on_draw/着replace_tiles/scoring三个DSL字段
读入但零引擎消费

修复:
- Deal(): replace_tiles="BEFORE_GAME_START"时开局扫描所有手牌换花牌
- ScoreEngine: 花牌计分(FlowerNormalScore×花牌数+配对花牌FlowerMatchScore)
- ScoringConfig: 新增FlowerNormalScore/FlowerMatchScore/FlowerMapping
- MahjongRoom: 从DSL读取花牌计分配置→传入ScoreEngine

Impact:
- Guangdong: BEFORE_GAME_START开局换花+花牌计分(每张1分+配对1分)
- Guobiao: on_draw replace运行时换花(已有) + 花牌不计分(DSL无scoring)
- Xuezhan/Wuhan: 无花牌,不受影响
This commit is contained in:
xiaoou
2026-07-04 20:29:50 +08:00
parent d95eab84f0
commit 9b9e4c310b
3 changed files with 260 additions and 1 deletions

View File

@ -10,6 +10,9 @@ public class ScoringConfig
public string FanStacking { get; set; } = "add";
public int PerWildcardBonus { get; set; } = 0;
public bool JiHuSelfDrawOnly { get; set; } = false;
public int FlowerNormalScore { get; set; } = 0;
public int FlowerMatchScore { get; set; } = 0;
public Dictionary<int, List<string>>? FlowerMapping { get; set; }
}
public class MahjongScoreEngine
@ -38,6 +41,23 @@ public class MahjongScoreEngine
if (_config.PerWildcardBonus > 0 && result.WildcardsUsed > 0)
baseFan += result.WildcardsUsed * _config.PerWildcardBonus;
// Flower bonus: e.g. Guangdong 每花牌+1分 + 配对花牌额外分
if (_config.FlowerNormalScore > 0 && state.FlowerPool.TryGetValue(winner, out var flowers) && flowers.Count > 0)
{
baseFan += flowers.Count * _config.FlowerNormalScore;
if (_config.FlowerMatchScore > 0 && _config.FlowerMapping != null)
{
// Count matching position+season pairs
var flowerNames = flowers.Select(f => FlowerName(f)).ToHashSet();
foreach (var (pos, names) in _config.FlowerMapping)
{
int matches = names.Count(n => flowerNames.Contains(n));
if (matches >= 2)
baseFan += _config.FlowerMatchScore;
}
}
}
baseFan = Math.Min(baseFan, _config.MaxCap);
if (isSelfDraw)
@ -134,4 +154,11 @@ public class MahjongScoreEngine
_ => 0
};
}
private static string FlowerName(int tile) => tile switch
{
41 => "春", 42 => "夏", 43 => "秋", 44 => "冬",
45 => "梅", 46 => "兰", 47 => "竹", 48 => "菊",
_ => "?"
};
}