fix: 交互模式逐回合展示 + Deal()公开 + 发牌输出修正
问题: 1. 交互模式 Run() 直接跑完整局,只渲染最终状态 2. RenderGame 手牌.OrderBy()排序,洗牌后仍显顺序 3. 牌墙剩余显示0因为游戏已跑完 修复: - 交互模式: room.Deal()→RenderDeal→逐回合StepTurn+ReadLine - 发牌输出: 显示每人张数 + 牌墙剩余,不排序手牌 - 每回合: 显示事件(摸/打/碰/杠/胡) + 当前手牌 - Run()保留用于自动模式
This commit is contained in:
147
Demo/Program.cs
147
Demo/Program.cs
@ -43,12 +43,10 @@ catch (Exception ex)
|
||||
return 1;
|
||||
}
|
||||
|
||||
Console.WriteLine($"=== 麻将规则引擎 Demo — {rules.Game.Name} === ({(autoMode ? "自动模式" : "交互模式")})");
|
||||
Console.WriteLine();
|
||||
|
||||
if (autoMode)
|
||||
{
|
||||
// Batch mode: run N rounds
|
||||
// Batch mode: run N rounds silently
|
||||
Console.WriteLine($"=== 麻将规则引擎 Demo — {rules.Game.Name} === (自动模式 {count}局)");
|
||||
int wins = 0, errors = 0;
|
||||
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
|
||||
|
||||
@ -78,53 +76,130 @@ if (autoMode)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interactive mode: single game with full output
|
||||
var room = new MahjongRoom(rules, new[] { "AI-东", "AI-南", "AI-西", "AI-北" }, autoMode: false);
|
||||
room.Run();
|
||||
// Interactive mode: step-by-step with key-press advancement
|
||||
Console.WriteLine($"=== 麻将规则引擎 Demo — {rules.Game.Name} === (交互模式,按 Enter 继续下一步)");
|
||||
Console.WriteLine();
|
||||
|
||||
RenderGame(room);
|
||||
var room = new MahjongRoom(rules, new[] { "AI-东", "AI-南", "AI-西", "AI-北" }, autoMode: false);
|
||||
room.Deal();
|
||||
|
||||
// Show dealt hands
|
||||
RenderDeal(room);
|
||||
Console.Write("\n[按 Enter 开始对局]");
|
||||
Console.ReadLine();
|
||||
|
||||
// Step through each turn
|
||||
int turnNumber = 0;
|
||||
while (!room.IsFinished)
|
||||
{
|
||||
turnNumber++;
|
||||
var events = room.StepTurn();
|
||||
|
||||
// Skip deal phase transition
|
||||
if (room.State.Phase == "deal") continue;
|
||||
|
||||
Console.WriteLine($"\n--- 第 {turnNumber} 回合 | 牌墙剩余 {room.State.Deck.Count} 张 ---");
|
||||
|
||||
// Show events for this turn
|
||||
foreach (var evt in events)
|
||||
{
|
||||
switch (evt.Type)
|
||||
{
|
||||
case "draw":
|
||||
Console.WriteLine($" [{evt.Player}] 摸牌: {MahjongTile.ToString(evt.Tile ?? 0)}");
|
||||
break;
|
||||
case "discard":
|
||||
Console.WriteLine($" [{evt.Player}] 出牌: {MahjongTile.ToString(evt.Tile ?? 0)}");
|
||||
break;
|
||||
case "pung":
|
||||
Console.WriteLine($" → {evt.Player}: 碰!{MahjongTile.ToString(evt.Tile ?? 0)}");
|
||||
break;
|
||||
case "ming_kong":
|
||||
Console.WriteLine($" → {evt.Player}: 明杠!{MahjongTile.ToString(evt.Tile ?? 0)}");
|
||||
break;
|
||||
case "win":
|
||||
Console.WriteLine($" ✅ {evt.Player}: 胡!{evt.Description}");
|
||||
break;
|
||||
case "deck_exhausted":
|
||||
Console.WriteLine($" ⚠ 牌墙耗尽!");
|
||||
break;
|
||||
case "hua_zhu":
|
||||
Console.WriteLine($" ⚠ {evt.Player}: 花猪(三色齐全)");
|
||||
break;
|
||||
case "hua_zhu_ok":
|
||||
break;
|
||||
case "ting_checked":
|
||||
Console.WriteLine($" ✓ {evt.Player}: 听牌");
|
||||
break;
|
||||
case "ting_failed":
|
||||
Console.WriteLine($" ✗ {evt.Player}: 未听牌");
|
||||
break;
|
||||
case "settle":
|
||||
Console.WriteLine($" 💰 结算");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Show current hands
|
||||
if (!room.IsFinished)
|
||||
{
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(" 当前手牌:");
|
||||
foreach (var p in room.State.PlayerOrder)
|
||||
{
|
||||
if (!room.State.AlivePlayers.Contains(p)) continue;
|
||||
var hand = room.State.Hands[p];
|
||||
Console.WriteLine($" {p}: {string.Join(" ", hand.OrderBy(t => t).Select(MahjongTile.ToString))} ({hand.Count}张)");
|
||||
}
|
||||
|
||||
Console.Write("\n[按 Enter 继续]");
|
||||
Console.ReadLine();
|
||||
}
|
||||
}
|
||||
|
||||
// Final render
|
||||
Console.WriteLine("\n══════════════════════════════════════");
|
||||
RenderFinal(room);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
void RenderGame(MahjongRoom room)
|
||||
void RenderDeal(MahjongRoom room)
|
||||
{
|
||||
var state = room.State;
|
||||
|
||||
Console.WriteLine("══════════════════════════════════════");
|
||||
Console.WriteLine("[发牌]");
|
||||
Console.WriteLine("═══ 发牌 ═══");
|
||||
foreach (var p in state.PlayerOrder)
|
||||
Console.WriteLine($" {p}{(p == state.Dealer ? "(庄)" : "")}: {string.Join(", ", state.Hands[p].OrderBy(t => t).Select(MahjongTile.ToString))} ({state.Hands[p].Count}张)");
|
||||
Console.WriteLine($" 牌墙剩余: {state.Deck.Count} 张");
|
||||
Console.WriteLine($" {p}{(p == state.Dealer ? " (庄)" : "")}: {state.Hands[p].Count}张");
|
||||
Console.WriteLine($" 牌墙: {state.Deck.Count} 张");
|
||||
Console.WriteLine($" (手牌已洗牌,按 Enter 查看牌局)");
|
||||
}
|
||||
|
||||
// Replay events
|
||||
foreach (var evt in state.RecentEvents)
|
||||
void RenderFinal(MahjongRoom room)
|
||||
{
|
||||
var state = room.State;
|
||||
Console.WriteLine("[最终状态]");
|
||||
Console.WriteLine($" 游戏结束,牌墙剩余 {state.Deck.Count} 张");
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(" 最终手牌:");
|
||||
foreach (var p in state.PlayerOrder)
|
||||
{
|
||||
if (evt.Type == "win")
|
||||
Console.WriteLine($" ✅ {evt.Player}: 自摸!番型: {evt.Description}");
|
||||
else if (evt.Type == "discard")
|
||||
Console.WriteLine($" [{evt.Player}] 出牌: {MahjongTile.ToString(evt.Tile ?? 0)}");
|
||||
else if (evt.Type == "pung")
|
||||
Console.WriteLine($" → {evt.Player}: 碰!");
|
||||
else if (evt.Type == "draw")
|
||||
Console.WriteLine($" [{evt.Player}] 摸牌: {MahjongTile.ToString(evt.Tile ?? 0)}");
|
||||
else if (evt.Type == "deck_exhausted")
|
||||
Console.WriteLine($" 牌墙耗尽!");
|
||||
else if (evt.Type == "hua_zhu")
|
||||
Console.WriteLine($" ⚠️ {evt.Player}: 花猪");
|
||||
else if (evt.Type == "ting_checked")
|
||||
Console.WriteLine($" ✓ {evt.Player}: 听牌");
|
||||
else if (evt.Type == "ting_failed")
|
||||
Console.WriteLine($" ❌ {evt.Player}: 未听牌");
|
||||
else if (evt.Type == "settle")
|
||||
Console.WriteLine($" 💰 结算");
|
||||
var hand = state.Hands[p];
|
||||
var sorted = string.Join(", ", hand.OrderBy(t => t).Select(MahjongTile.ToString));
|
||||
Console.WriteLine($" {p}{(p == state.Dealer ? "(庄)" : "")}: {sorted} ({hand.Count}张)");
|
||||
}
|
||||
|
||||
if (state.HuPlayers.Count > 0)
|
||||
{
|
||||
Console.WriteLine();
|
||||
Console.WriteLine($" 胡牌: {string.Join(", ", state.HuPlayers)}");
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("[最终结算]");
|
||||
foreach (var (p, score) in state.Scores)
|
||||
Console.WriteLine($" {p}: {(score >= 0 ? "+" : "")}{score}分");
|
||||
Console.WriteLine($" {p}: {(score >= 0 ? "+" : "")}{score}分");
|
||||
int total = state.Scores.Values.Sum();
|
||||
Console.WriteLine($" 总分: {(total >= 0 ? "+" : "")}{total} {(total == 0 ? "✓" : "⚠️ 非零和")}");
|
||||
Console.WriteLine($" 总分: {(total >= 0 ? "+" : "")}{total} {(total == 0 ? "✓" : "⚠ 非零和")}");
|
||||
Console.WriteLine("══════════════════════════════════════");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user