using OECS; namespace Blackjack; /// /// Renders the current game state to the console. /// public class RenderSystem : ISystem { public void Run(World world) { var state = world.ReadSingleton(); Console.WriteLine(); Console.WriteLine(" Blackjack"); Console.WriteLine(" ═════════"); Console.WriteLine(); Console.WriteLine($" Chips: {state.Chips} | Round: {state.RoundNumber}"); Console.WriteLine(); // Show dealer's hand. var dealerTotal = HandUtil.CalculateHand(world, DealerHandTag.Instance); Console.Write(" Dealer: "); if (state.Phase == GamePhase.PlayerTurn) { // Hide first card (hole card) during player's turn. Console.Write("?? "); PrintHand(world, DealerHandTag.Instance, skipFirst: true); } else { PrintHand(world, DealerHandTag.Instance); Console.Write($" ({dealerTotal})"); } Console.WriteLine(); // Show player's hand. var playerTotal = HandUtil.CalculateHand(world, PlayerHandTag.Instance); Console.Write(" Player: "); PrintHand(world, PlayerHandTag.Instance); Console.Write($" ({playerTotal})"); Console.WriteLine(); Console.WriteLine(); // Status line. switch (state.Phase) { case GamePhase.Betting: Console.Write($" Enter bet (1–{state.Chips}): "); break; case GamePhase.PlayerTurn: Console.Write(" [H]it or [S]tand: "); break; case GamePhase.RoundOver: Console.WriteLine($" {ResultText(state.Result)}"); Console.WriteLine(); Console.Write(" Press Enter for next round..."); break; default: break; } } private static void PrintHand(World world, DealerHand hand, bool skipFirst = false) { PrintHandImpl(world, hand, skipFirst); } private static void PrintHand(World world, PlayerHand hand) { PrintHandImpl(world, hand, skipFirst: false); } private static void PrintHandImpl(World world, T handTag, bool skipFirst) where T : struct { Entity handEntity = Entity.Null; using (var iter = world.Select()) { while (iter.MoveNext()) { if (iter.CurrentEntity != World.SingletonEntity) { handEntity = iter.CurrentEntity; break; } } } if (handEntity == Entity.Null) return; var cards = world.GetSources(handEntity); var ordered = cards.OrderByDescending(c => { var card = world.ReadComponent(c); return (int)card.Rank; }).ToList(); bool first = true; foreach (var cardEntity in ordered) { if (skipFirst && first) { first = false; continue; } first = false; var card = world.ReadComponent(cardEntity); Console.Write(CardToString(card)); Console.Write(" "); } } private static string CardToString(Card card) { var suit = card.Suit switch { Suit.Hearts => "♥", Suit.Diamonds => "♦", Suit.Clubs => "♣", Suit.Spades => "♠", _ => "?" }; var rank = card.Rank switch { Rank.Ace => "A", Rank.Jack => "J", Rank.Queen => "Q", Rank.King => "K", _ => ((int)card.Rank).ToString() }; return $"{rank}{suit}"; } private static string ResultText(RoundResult result) => result switch { RoundResult.PlayerBust => "You bust! Dealer wins.", RoundResult.DealerBust => "Dealer busts! You win!", RoundResult.PlayerWin => "You win!", RoundResult.DealerWin => "Dealer wins.", RoundResult.Push => "Push — it's a tie!", RoundResult.Blackjack => "Blackjack!", _ => "" }; }