oecs-sharp/Game.Blackjack/Systems/DeckSetupSystem.cs

69 lines
2.4 KiB
C#
Raw Normal View History

2026-07-18 23:26:56 +08:00
using OECS;
namespace Game.Blackjack;
2026-07-18 23:26:56 +08:00
/// <summary>
/// Creates the deck (52 cards + deck/hand entities) and shuffles
/// using mulberry32 with the seed from the GameState singleton.
/// Runs once at the start of each round (during Dealing phase).
/// </summary>
public class DeckSetupSystem : ISystem
{
public void RunImpl(World world)
2026-07-18 23:26:56 +08:00
{
var state = world.ReadSingleton<GameState>();
if (state.Phase != GamePhase.Dealing)
return;
// Only create deck entities if they don't exist yet.
bool hasDeck = false;
using (var iter = world.Select<Deck>())
{
hasDeck = iter.MoveNext();
2026-07-18 23:26:56 +08:00
}
if (!hasDeck)
{
// Create deck entity.
var deckEntity = world.CreateEntity();
world.AddComponent(deckEntity, new Deck());
// Create all 52 cards.
foreach (Suit suit in Enum.GetValues<Suit>())
{
foreach (Rank rank in Enum.GetValues<Rank>())
{
var cardEntity = world.CreateEntity();
world.AddComponent(cardEntity, new Card { Suit = suit, Rank = rank });
world.AddComponent(cardEntity, new InDeck { Target = deckEntity });
2026-07-18 23:26:56 +08:00
}
}
// Create hand entities.
var playerHand = world.CreateEntity();
world.AddComponent(playerHand, new PlayerHand());
var dealerHand = world.CreateEntity();
world.AddComponent(dealerHand, new DealerHand());
}
// Shuffle the deck using mulberry32 with the current seed.
ref var mutableState = ref world.GetSingleton<GameState>();
var deckEntity2 = world.FindEntity<Deck>();
2026-07-18 23:26:56 +08:00
var cards = world.GetSources<InDeck>(deckEntity2).ToArray();
Shuffle(world, deckEntity2, cards, ref mutableState.Seed);
}
private static void Shuffle(World world, Entity deckEntity, Entity[] cardEntities, ref uint seed)
{
// Fisher-Yates shuffle using mulberry32.
for (int i = cardEntities.Length - 1; i > 0; i--)
{
int j = Mulberry32.NextInt(ref seed, 0, i);
(cardEntities[i], cardEntities[j]) = (cardEntities[j], cardEntities[i]);
}
// Reorder the source set in-place — no component add/remove needed.
world.ReorderSources<InDeck>(deckEntity, cardEntities);
2026-07-18 23:26:56 +08:00
}
}