namespace MauMau_Server.Mau; public class Deck { private readonly List _unusedDeck = new(); private readonly List _usedDeck = new(); public Card CurrentCard { get; private set; } /** * * Creates a new deck instance with a new shuffled set of cards * */ public Deck() { // Create a new set of cards CreateSet(); // Shuffle the deck ShuffleDeck(); // Draw the first card var initialCard = DrawCard(); // Set the current card to the first card CurrentCard = initialCard; } /** * * Adds the given card to the used cards deck and sets the current card to the given card. * * The card to add to the used cards deck. */ public void AddCardToUsedDeck(Card card) { // Add the card to the used deck _usedDeck.Add(card); // Set the current card to the given card CurrentCard = card; } /** * * Adds the given list of cards to the used cards deck. * * The list of cards to add to the used cards deck. */ public void AddCardsToUsedDeck(IEnumerable cards) { _usedDeck.AddRange(cards); } /** * * Draws a card from the deck. * If the deck is empty, the deck is reshuffled with . * */ public Card DrawCard() { // Check if the deck is empty, if so, reshuffle it if (_unusedDeck.Count == 0) ReshuffleDeck(); // Grab the first card from the deck and remove it var card = _unusedDeck[0]; _unusedDeck.RemoveAt(0); return card; } /** * * Take a given amount of cards from the deck. This method calls for each card. * * The amount of cards to draw from the deck. */ public IEnumerable DrawCards(int amount) { // Create a list of cards and add the drawn cards to it var cards = new List(); for (var i = 0; i < amount; i++) { cards.Add(DrawCard()); } return cards; } /** * * Creates a new deck of cards and adds them to the unused deck. * */ private void CreateSet() { foreach (CardType cardType in Enum.GetValues(typeof(CardType))) { if (cardType == CardType.JOKER) { _unusedDeck.Add(new Card(cardType, CardValue.RED)); _unusedDeck.Add(new Card(cardType, CardValue.BLACK)); continue; } foreach (CardValue cardValue in Enum.GetValues(typeof(CardValue))) { if (cardValue is CardValue.RED or CardValue.BLACK) continue; _unusedDeck.Add(new Card(cardType, cardValue)); } } } /** * * Moves all the used cards back to the unused deck and shuffles it. * If there are no cards to reshuffle, a new set of cards is created and shuffled. * */ private void ReshuffleDeck() { // Move all used cards back to the unused deck _unusedDeck.AddRange(_usedDeck); _usedDeck.Clear(); // If there are no cards left, create a new set and add it if (!_unusedDeck.Any()) { CreateSet(); } // Shuffle the deck ShuffleDeck(); } /** * * Shuffles all the cards in the deck using the Fisher-Yates algorithm. * */ private void ShuffleDeck() { // Clear the unused ceck var unusedDeckCopy = new List(_unusedDeck); _unusedDeck.Clear(); // Shuffle the deck unusedDeckCopy = unusedDeckCopy.OrderBy(x => Guid.NewGuid()).ToList(); // Add the shuffled deck back to the unused deck _unusedDeck.AddRange(unusedDeckCopy); } }