feat: 新增4个番型识别器—三风/双箭刻/一色三同顺/一般高

4个新识别器均基于已有统计逻辑:
- 三风: windKezi==3 (复用大四喜/小四喜的风刻统计)
- 双箭刻: dragonKezi==2 (复用大三元/小三元的箭刻统计)
- 一色三同顺: shunziGroups count>=3 (复用一色四同顺分组)
- 一般高: shunziGroups count>=2

同步更新: enginePatterns + IdentifyFans well-known filter

效果: 国标--check警告 12→6 (消除三风×2/双箭刻×2/三同顺/一般高)
剩余6个: 圈风/门风/单钓将×3/四归一(需新状态跟踪)
This commit is contained in:
xiaoou
2026-07-04 23:25:13 +08:00
parent 488e96114f
commit 816000a286
2 changed files with 12 additions and 5 deletions

View File

@ -65,8 +65,8 @@ public class CapabilityRegistry
"带幺九","全带幺","混幺九","缺一门","平胡","平和","断幺九", "带幺九","全带幺","混幺九","缺一门","平胡","平和","断幺九",
"全大","全中","全小","全双","大于五","小于五", "全大","全中","全小","全双","大于五","小于五",
"十三幺","全不靠","一色双龙会","连七对", "十三幺","全不靠","一色双龙会","连七对",
"将一色","大四喜","大三元","小四喜","小三元", "将一色","大四喜","大三元","小四喜","小三元","三风","双箭刻",
"一色四同顺","五门齐","全求人","门前清", "一色四同顺","一色三同顺","一般高","五门齐","全求人","门前清",
"鸡胡","癞子胡", "鸡胡","癞子胡",
"杠上开花","海底捞月","抢杠胡","天胡","地胡", "杠上开花","海底捞月","抢杠胡","天胡","地胡",
"将","无字" // base_fan:0/1 markers "将","无字" // base_fan:0/1 markers

View File

@ -710,10 +710,12 @@ public class MeldsSolver
var keziTiles = melds.Where(m => m.Type == "kezi").SelectMany(m => m.Tiles).Where(t => t > 0); var keziTiles = melds.Where(m => m.Type == "kezi").SelectMany(m => m.Tiles).Where(t => t > 0);
int windKezi = keziTiles.Where(t => t >= 31 && t <= 34).GroupBy(t => t).Count(g => g.Count() >= 3); int windKezi = keziTiles.Where(t => t >= 31 && t <= 34).GroupBy(t => t).Count(g => g.Count() >= 3);
if (windKezi == 4) fans.Add("大四喜"); if (windKezi == 4) fans.Add("大四喜");
if (windKezi == 3) fans.Add("三风");
// 大三元: 3 dragon kongs/pungs (中35,发36,白37) // 大三元: 3 dragon kongs/pungs (中35,发36,白37)
int dragonKezi = keziTiles.Where(t => t >= 35 && t <= 37).GroupBy(t => t).Count(g => g.Count() >= 3); int dragonKezi = keziTiles.Where(t => t >= 35 && t <= 37).GroupBy(t => t).Count(g => g.Count() >= 3);
if (dragonKezi == 3) fans.Add("大三元"); if (dragonKezi == 3) fans.Add("大三元");
if (dragonKezi == 2) fans.Add("双箭刻");
// 小四喜: 3 wind kezi + wind pair // 小四喜: 3 wind kezi + wind pair
var pairTiles = pair.Where(t => t > 0); var pairTiles = pair.Where(t => t > 0);
@ -726,11 +728,16 @@ public class MeldsSolver
if (dragonKezi == 2 && dragonPair && pairTiles.Any(t => t >= 35 && t <= 37)) if (dragonKezi == 2 && dragonPair && pairTiles.Any(t => t >= 35 && t <= 37))
fans.Add("小三元"); fans.Add("小三元");
// 一色四同顺: four identical sequences in same suit // 一色四同顺/一色三同顺/一般高: grouped by identical sequences
var shunziGroups = melds.Where(m => m.Type == "shunzi") var shunziGroups = melds.Where(m => m.Type == "shunzi")
.GroupBy(m => string.Join(",", m.Tiles.OrderBy(t => t))); .GroupBy(m => string.Join(",", m.Tiles.OrderBy(t => t)));
if (shunziGroups.Any(g => g.Count() >= 4)) if (shunziGroups.Any(g => g.Count() >= 4))
fans.Add("一色四同顺"); fans.Add("一色四同顺");
foreach (var g in shunziGroups)
{
if (g.Count() >= 3) fans.Add("一色三同顺");
if (g.Count() >= 2) fans.Add("一般高");
}
// 五门齐: all 5 tile categories present (3 suits + honors + at least one terminal) // 五门齐: all 5 tile categories present (3 suits + honors + at least one terminal)
var categories = new HashSet<int>(); var categories = new HashSet<int>();
@ -787,8 +794,8 @@ public class MeldsSolver
f is "清一色" or "混一色" or "对对胡" or "碰碰和" or "暗七对" or "七对" f is "清一色" or "混一色" or "对对胡" or "碰碰和" or "暗七对" or "七对"
or "带幺九" or "十三幺" or "字一色" or "断幺九" or "无字" or "将" or "带幺九" or "十三幺" or "字一色" or "断幺九" or "无字" or "将"
or "缺一门" or "平胡" or "全大" or "全中" or "全小" or "全双" or "缺一门" or "平胡" or "全大" or "全中" or "全小" or "全双"
or "将一色" or "大四喜" or "大三元" or "小四喜" or "小三元" or "将一色" or "大四喜" or "大三元" or "小四喜" or "小三元" or "三风" or "双箭刻"
or "一色四同顺" or "五门齐" or "全求人" or "门前清" or "一色四同顺" or "一色三同顺" or "一般高" or "五门齐" or "全求人" or "门前清"
or "鸡胡" or "癞子胡" or "平和" or "鸡胡" or "癞子胡" or "平和"
or "杠上开花" or "海底捞月" or "抢杠胡" or "天胡" or "地胡").ToList(); or "杠上开花" or "海底捞月" or "抢杠胡" or "天胡" or "地胡").ToList();
} }