114 lines
3.9 KiB
C#
114 lines
3.9 KiB
C#
|
|
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<GameState>();
|
||
|
|
|
||
|
|
// 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<GameState>();
|
||
|
|
roundState.RoundNumber++;
|
||
|
|
world.MarkModified<GameState>(World.SingletonEntity);
|
||
|
|
world.PostChanges();
|
||
|
|
world.Commands.Enqueue(new NewRoundCommand());
|
||
|
|
break;
|
||
|
|
|
||
|
|
default:
|
||
|
|
// Dealing, DealerTurn — systems handle these automatically.
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
group.RunLogical();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|