using OECS;
namespace Game.Blackjack;
///
/// 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).
///
public class DeckSetupSystem : ISystem
{
public void RunImpl(World world)
{
var state = world.ReadSingleton();
if (state.Phase != GamePhase.Dealing)
return;
// Only create deck entities if they don't exist yet.
bool hasDeck = false;
using (var iter = world.Select())
{
hasDeck = iter.MoveNext();
}
if (!hasDeck)
{
// Create deck entity.
var deckEntity = world.CreateEntity();
world.AddComponent(deckEntity, new Deck());
// Create all 52 cards.
foreach (Suit suit in Enum.GetValues())
{
foreach (Rank rank in Enum.GetValues())
{
var cardEntity = world.CreateEntity();
world.AddComponent(cardEntity, new Card { Suit = suit, Rank = rank });
world.AddComponent(cardEntity, new InDeck { Target = deckEntity });
}
}
// 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();
var deckEntity2 = world.FindEntity();
var cards = world.GetSources(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(deckEntity, cardEntities);
}
}