using OECS; namespace Blackjack; public static class Program { public static void Main() { var world = new World(); // ── Initialize game state ───────────────────────────────────── // Use a seed based on current time, or a fixed seed for reproducibility. uint seed = (uint)Environment.TickCount; // Uncomment the next line for a deterministic game: // seed = 12345u; world.SetSingleton(new GameState { Phase = GamePhase.Betting, Result = RoundResult.None, Chips = 100, CurrentBet = 0, RoundNumber = 1, Seed = seed }); world.PostChanges(); // ── Wire up systems ─────────────────────────────────────────── var group = new SystemGroup(world); group.Add(new DeckSetupSystem()); group.Add(new DealSystem()); group.Add(new PlayerBustCheckSystem()); group.Add(new DealerSystem()); group.Add(new RenderSystem()); // ── Game loop ───────────────────────────────────────────────── group.RunLogical(); while (true) { var state = world.ReadSingleton(); // Check for game over (out of chips). if (state.Chips <= 0 && state.Phase == GamePhase.Betting) { Console.WriteLine(); Console.WriteLine(" You're out of chips! Game over."); break; } switch (state.Phase) { case GamePhase.Betting: var input = Console.ReadLine(); if (string.IsNullOrWhiteSpace(input)) continue; if (input.Trim().ToLower() == "quit") return; if (int.TryParse(input.Trim(), out var bet)) { world.Commands.Enqueue(new PlaceBetCommand { Amount = bet }); } else { Console.WriteLine(" Invalid bet. Enter a number."); continue; } break; case GamePhase.PlayerTurn: var choice = Console.ReadLine(); if (string.IsNullOrWhiteSpace(choice)) continue; if (choice.Trim().ToLower() == "quit") return; switch (choice.Trim().ToLower()) { case "h": case "hit": world.Commands.Enqueue(new HitCommand()); break; case "s": case "stand": world.Commands.Enqueue(new StandCommand()); break; default: Console.WriteLine(" Invalid choice. Enter H or S."); continue; } break; case GamePhase.RoundOver: Console.ReadLine(); ref var roundState = ref world.GetSingleton(); roundState.RoundNumber++; world.MarkModified(World.SingletonEntity); world.PostChanges(); world.Commands.Enqueue(new NewRoundCommand()); break; default: // Dealing, DealerTurn — systems handle these automatically. break; } group.RunLogical(); } } }