From d83494e6692fc87a8061d3bc2525bffbb664ef3c Mon Sep 17 00:00:00 2001 From: xiaoou Date: Sun, 5 Jul 2026 00:20:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20demo=E6=98=BE=E7=A4=BA=E5=90=AC?= =?UTF-8?q?=E7=89=8C=E7=8A=B6=E6=80=81+=E5=8F=AF=E8=83=A1=E5=BC=A0?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 引擎: MahjongRoom.GetTingTiles(player) 返回所有可胡的unique tile Demo: 每回合后显示'听牌: X: 🀄听N张(tile1 tile2...) | Y: 未听...' 包含已胡/副露中的tile计数,兼容wildcard和258规则 示例: 听牌: AI-东: 🀄听 1张(中) | AI-南: 未听 | AI-西: 未听 | AI-北: 未听 --- Demo/Program.cs | 16 +++++++++++++++- RuleEngine/MahjongRoom.cs | 20 ++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Demo/Program.cs b/Demo/Program.cs index 51302e8..d659747 100644 --- a/Demo/Program.cs +++ b/Demo/Program.cs @@ -174,10 +174,24 @@ else } } + // 听牌检测: 每回合后显示各玩家听牌状态 + var tingInfo = new List(); + foreach (var p in room.State.AlivePlayers) + { + var tingTiles = room.GetTingTiles(p); + if (tingTiles.Count > 0) + { + var tileNames = tingTiles.Select(MahjongTile.ToString); + tingInfo.Add($"{p}: 🀄听 {tingTiles.Count}张({string.Join(" ", tileNames)})"); + } + else + tingInfo.Add($"{p}: 未听"); + } + Console.WriteLine($" 听牌: {string.Join(" | ", tingInfo)}"); + // Show current hands if (!room.IsFinished) { - // In human mode, show only opponent hands (human HUD shows their own) Console.WriteLine(); if (humanMode) { diff --git a/RuleEngine/MahjongRoom.cs b/RuleEngine/MahjongRoom.cs index bdb9dc3..30f5821 100644 --- a/RuleEngine/MahjongRoom.cs +++ b/RuleEngine/MahjongRoom.cs @@ -892,4 +892,24 @@ public class MahjongRoom State.Phase = "settle"; State.AddEvent("settle", "", null, "结算"); } + + /// 返回玩家可胡牌的所有unique tile列表(听牌检测)。Empty=未听. + public List GetTingTiles(string player) + { + var result = new List(); + bool require258 = _rules.WinCondition?.PairMustBe258 ?? false; + var allPossible = MahjongTile.AllTiles(_rules.Deck.IncludeHonors, false); + var hand = State.Hands[player]; + + foreach (var tile in allPossible) + { + int alreadyHave = hand.Count(t => t == tile); + if (alreadyHave >= 4) continue; + var checkHand = new List(hand) { tile }; + int wc = CountWildcardsInHand(checkHand); + var r = _solver.CheckWin(hand, newTile: tile, wildcardCount: wc, require258Pair: require258); + if (r != null && r.IsWin) result.Add(tile); + } + return result; + } }