async public Task <Deck> CreateNewShuffledDeckAsync(int deckCount)
        {
            var random = new Random();

            var suits  = new[] { "HEARTS", "SPADES", "CLUBS", "DIAMONDS" };
            var values = new[] { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "JACK", "QUEEN", "KING" };
            var cards  = new Card[52 * deckCount];
            var deck   = new Deck {
                DeckId = random.Next().ToString("X")
            };

            int newCardIndex = 0;

            for (int _ = 0; _ < deckCount; _ += 1)
            {
                foreach (string suit in suits)
                {
                    foreach (string value in values)
                    {
                        string code = value.Substring(0, 1) + suit.Substring(0, 1);
                        if (value == "10")
                        {
                            code = "0" + suit.Substring(0, 1);
                        }
                        cards[newCardIndex] = new Card
                        {
                            Deck  = deck,
                            Value = value,
                            Suit  = suit,
                            Code  = code,
                        };
                        newCardIndex += 1;
                    }
                }
            }

            // Fisher-Yates shuffle
            for (int cardIndex = cards.Length - 1; cardIndex >= 0; cardIndex -= 1)
            {
                int  swapIndex = random.Next(0, cardIndex);
                Card card      = cards[swapIndex];
                cards[swapIndex]       = cards[cardIndex];
                cards[cardIndex]       = card;
                cards[cardIndex].Order = cardIndex;
                cards[swapIndex].Order = swapIndex;
            }

            foreach (Card card in cards)
            {
                deck.Cards.Add(card);
            }

            using (var context = new DeckContext())
            {
                context.Decks.Add(deck);
                await context.SaveChangesAsync();
            }

            return(deck);
        }
Beispiel #2
0
        /// <summary>
        /// Shuffles the cards of a pile in a given deck.
        /// </summary>
        /// <param name="deckId">The ID of the deck.</param>
        /// <param name="pileName">The name of the pile.</param>
        /// <returns>True if the shuffle was successful; false otherwise.</returns>
        public async Task <bool> ShufflePileAsync(string deckId, string pileName)
        {
            using (var context = new DeckContext())
            {
                var deck = await context.Decks
                           .Include(d => d.Cards)
                           .Include(d => d.Piles)
                           .SingleAsync(d => d.DeckId == deckId);

                var piles = deck.Piles;
                var pile  = piles.Single(p => p.Name == pileName);
                var cards = pile.Cards.ToList();

                try
                {
                    Shuffle(cards);
                    pile.Cards = cards;
                    await context.SaveChangesAsync();

                    return(true);
                }
                catch
                {
                    return(false);
                }
            }
        }
        async public Task <Deck> DrawCardsAsync(string deckId, int numberToDraw)
        {
            using (var context = new DeckContext())
            {
                Deck deck = await context.Decks
                            .Include(x => x.Cards)
                            .SingleAsync(x => x.DeckId == deckId);

                foreach (Card card in deck.Cards)
                {
                    if (!card.Drawn)
                    {
                        card.Drawn    = true;
                        numberToDraw -= 1;
                    }
                    if (numberToDraw == 0)
                    {
                        break;
                    }
                }

                await context.SaveChangesAsync();

                return(deck);
            }
        }
Beispiel #4
0
 /// <summary>
 /// Returns a deck with the given ID.
 /// </summary>
 /// <param name="deckId">The ID of the deck.</param>
 /// <returns>The deck.</returns>
 public async Task <Deck> GetDeckAsync(string deckId)
 {
     using (var context = new DeckContext())
     {
         return(await context.Decks
                .Include(d => d.Cards)
                .Include(d => d.Piles)
                .SingleAsync(d => d.DeckId == deckId));
     }
 }
Beispiel #5
0
        /// <summary>
        /// Puts a collection of cards of a given deck in a pile.
        /// </summary>
        /// <param name="deckId">The ID of the deck.</param>
        /// <param name="pileName">The name of the pile.</param>
        /// <param name="cardCodes">The codes of the cards to put in the pile.</param>
        /// <returns>The updated deck.</returns>
        public async Task <Deck> AddToPileAsync(string deckId, string pileName, string[] cardCodes)
        {
            using (var context = new DeckContext())
            {
                var deck = await context.Decks
                           .Include(d => d.Cards)
                           .Include(d => d.Piles)
                           .SingleAsync(d => d.DeckId == deckId);

                // TODO Confirm that cards to add are all drawn

                // I'm not sure how to best format these LINQ statements
                if (!deck.Piles
                    .Select(p => p.Name)
                    .Contains(pileName))
                {
                    deck.Piles.Add(new Pile()
                    {
                        Name   = pileName,
                        DeckId = deck.Id
                    });
                }

                // I don't know if I can just modify the pileIds of each card without
                // modifying all the piles in the deck.
                //
                // This will also break when a deck has multiple copies of the same card
                // (e.g. when the CreateNewShuffledDeckAsync method is passed an int > 1)
                // because I'm filtering by card code instead of card id.
                //
                // Perhaps this can be fixed if we require a "source" field in the request.
                var cards = deck.Cards
                            .Where(c => cardCodes.Contains(c.Code))
                            .ToList();

                cards.ForEach(c =>
                {
                    if (c.PileId.HasValue)
                    {
                        deck.Piles
                        .Single(p => p.Id == c.PileId.Value)
                        .Cards
                        .Remove(c);
                    }
                });

                var pile = deck.Piles.Single(p => p.Name == pileName);
                pile.Cards = pile.Cards.Concat(cards).ToList();
                await context.SaveChangesAsync();

                return(deck);
            }
        }
        async public Task <Deck> GetDeck(string deckId)
        {
            using (var context = new DeckContext())
            {
                Deck deck = await context.Decks
                            .Include(x => x.Cards)
                            .Include(x => x.Piles)
                            .SingleAsync(x => x.DeckId == deckId);

                return(deck);
            }
        }
        async public Task <Deck> PutCardsInPile(string deckId, string pileName, List <string> cardCodes)
        {
            using (var context = new DeckContext())
            {
                Deck deck = await context.Decks
                            .Include(x => x.Cards)
                            .Include(x => x.Piles)
                            .SingleAsync(x => x.DeckId == deckId);

                Pile pile = null;

                foreach (Pile p in deck.Piles)
                {
                    if (p.Name == pileName)
                    {
                        pile = p;
                    }
                }
                if (pile == null)
                {
                    //create new pile
                    pile = new Pile()
                    {
                        Name   = pileName,
                        DeckId = deck.Id,
                        Deck   = deck
                    };
                    context.Piles.Add(pile);
                    context.SaveChanges();
                    pile = context.Piles
                           .Include(p => p.Cards)
                           .First(p => p.DeckId == deck.Id && p.Name == pileName);
                }


                foreach (Card card in deck.Cards)
                {
                    foreach (string cardCode in cardCodes)
                    {
                        if (card.Code == cardCode)
                        {
                            card.PileId = pile.Id;
                        }
                    }
                }

                await context.SaveChangesAsync();

                return(deck);
            }
        }
Beispiel #8
0
        async public Task <Pile> AddCardToPileAsync(string deckId, string pileName, string cards)
        {
            string[] cardArr = cards.Split(',');
            using (var context = new DeckContext())
            {
                Deck deck = await context.Decks
                            .Include(x => x.Cards)
                            .SingleAsync(x => x.DeckId.Equals(deckId));

                Deck deckPiles = await context.Decks
                                 .Include(x => x.Piles)
                                 .SingleAsync(x => x.DeckId.Equals(deckId));

                //Couldn't figure out how to do multiple includes so I made two

                Pile pile;
                try
                {
                    pile = deckPiles.Piles.Single(x => x.Name.Equals(pileName) && x.DeckId == deckPiles.Id);
                }
                catch (Exception)
                {
                    pile        = new Pile();
                    pile.Deck   = deckPiles;
                    pile.DeckId = deckPiles.Id;
                    pile.Name   = pileName;
                    pile.Cards  = new List <Card>();
                    deckPiles.Piles.Add(pile);
                }

                foreach (var card in cardArr)
                {
                    Card Card = deck.Cards.Single(x => x.Code.Equals(card));
                    Card.Drawn = true; // we took it out so it's out of the deck
                    if (pile.Cards.Contains(Card))
                    {
                        continue;                            //small check so we won't put multiple instances of the same card in the pile
                    }
                    pile.Cards.Add(Card);
                    Card.Pile = pile;
                }

                await context.SaveChangesAsync();

                return(pile);
            }
        }
Beispiel #9
0
        /// <summary>
        /// Draws a number of cards from a given deck.
        /// </summary>
        /// <param name="deckId">The ID of the deck.</param>
        /// <param name="numCards">The number of cards to draw.</param>
        /// <returns>The updated deck.</returns>
        public async Task <Deck> DrawCardsAsync(string deckId, int numCards)
        {
            using (var context = new DeckContext())
            {
                var deck = await context.Decks
                           .Include(d => d.Cards)
                           .SingleAsync(d => d.DeckId == deckId);

                // TODO handle the case when there are not enough cards to draw
                var notDrawn = deck.Cards
                               .Where(c => !c.Drawn)
                               .Take(numCards)
                               .ToList();
                notDrawn.ForEach(c => c.Drawn = !c.Drawn);
                await context.SaveChangesAsync();

                return(deck);
            }
        }
Beispiel #10
0
        async public Task <Pile> PileShuffleAsync(string deckId, string pileName)
        {
            using (var context = new DeckContext())
            {
                Pile pile = await context.Piles
                            .Include(x => x.Cards)
                            .SingleAsync(x => x.Name.Equals(pileName));

                //no try catch this time because if you try to shuffle a pile that doesn't exist you deserve to have the API scream at you
                /*Pile pile = deckPiles.Piles.Single(x => x.Name.Equals(pileName) && x.DeckId == deckPiles.Id);*/
                var rnd          = new Random();
                var shuffledPile = pile.Cards.OrderBy(x => rnd.Next()).ToList();

                pile.Cards = shuffledPile;

                await context.SaveChangesAsync();

                return(pile);
            }
        }