Beispiel #1
0
        public void SelectCards()
        {
            if (this.State != GameState.CardSelection)
            {
                throw new GameCreationException("This method can only be called during CardSelection!");
            }

            if (_Table != null)
            {
                _Table.TearDown();
            }

            this.CardsAvailable = Cards.CardCollection.GetAllCards(c => IsCardAllowed(c));
            Cards.CardCollection _CardsChosen = new Cards.CardCollection();

            if (this.Settings.Preset != null)
            {
                _CardsChosen = this.Settings.Preset.Cards;
            }
            else if (this.Settings.Constraints != null)
            {
                _CardsChosen.AddRange(this.Settings.Constraints.SelectCards(this.CardsAvailable, 10));
            }

            this.CardsAvailable.RemoveAll(card => _CardsChosen.Contains(card));
            _Table = new Table(this, this.Players.Count);
            _CardsChosen.ForEach(c => _Table.AddKingdomSupply(_Players, c.CardType));

            // should now have a list of cards that can be drawn from for things like Bane supplies

            _Table.SetupSupplies(this);
        }
Beispiel #2
0
        public IList <DominionBase.Cards.Card> SelectCards(IList <Cards.Card> availableCards, int numberCardsToSelect)
        {
            List <Cards.Card> _CardsChosen = new List <Cards.Card>();

            // Remove all "CardDontUse" constraint cards first
            IList <Cards.Card> usableCards = new List <Cards.Card>(availableCards);

            foreach (Cards.Constraint constraint in this.Where(c => c.ConstraintType == Cards.ConstraintType.CardDontUse))
            {
                foreach (Cards.Card card in constraint.GetMatchingCards(availableCards))
                {
                    usableCards.Remove(card);
                }
            }

            IEnumerable <Constraint> usableConstraints = this.Where(c => c.ConstraintType != Cards.ConstraintType.CardDontUse);

            Dictionary <Cards.Constraint, IList <Cards.Card> > constraintCards = new Dictionary <Cards.Constraint, IList <Cards.Card> >();

            foreach (Cards.Constraint constraint in usableConstraints)
            {
                constraintCards[constraint] = new Cards.CardCollection(constraint.GetMatchingCards(availableCards));
            }

            int attempts = 0;

            // Satisfy Minimum constraints first
            do
            {
                attempts++;
                _CardsChosen.Clear();

                // Add in required cards first
                foreach (Cards.Constraint constraint in usableConstraints.Where(c => c.ConstraintType == Cards.ConstraintType.CardMustUse))
                {
                    _CardsChosen.AddRange(constraintCards[constraint]);
                }

                if (_CardsChosen.Count > numberCardsToSelect)
                {
                    throw new ConstraintException(String.Format("Too many required cards specified in constraints!  Please double-check your setup and loosen the requirements.  {0} needed & found {1} required constraints.", numberCardsToSelect, _CardsChosen.Count));
                }

                foreach (Cards.Constraint constraint in usableConstraints.OrderByDescending(c => c.Minimum))
                {
                    if (constraint.MinimumMet(_CardsChosen))
                    {
                        continue;
                    }

                    CardCollection discardCards = new CardCollection();
                    Utilities.Shuffler.Shuffle(constraintCards[constraint]);
                    foreach (Cards.Card card in constraintCards[constraint])
                    {
                        if (discardCards.Contains(card))
                        {
                            continue;
                        }

                        if (this.IsChoosable(_CardsChosen, card))
                        {
                            _CardsChosen.Add(card);
                            if (constraint.MinimumMet(_CardsChosen))
                            {
                                break;
                            }
                            // Certain constraints (like NumberOfSets) immediately disallow other cards when a card is chosen.
                            // We need to get the list of disallowed cards after each card is added to the list.
                            // This is only needed to ensure the Minimum constraint without taking 10k iterations
                            discardCards.AddRange(constraint.GetCardsToDiscard(_CardsChosen, constraintCards[constraint]));
                        }
                    }
                }

                // Give it 50 attempts at trying to satisfy the Minimum requirements
                if (attempts > 50)
                {
                    throw new ConstraintException("Cannot satisfy specified constraints!  Please double-check and make sure it's possible to construct a Kingdom card setup with the constraints specified.");
                }
            } while (!this.MinimumMet(_CardsChosen) || _CardsChosen.Count > numberCardsToSelect);

            // After satisfying the Minimums, Maximums should be pretty easy to handle
            List <Cards.Card> _CardsChosenNeeded = new List <Cards.Card>(_CardsChosen);

            attempts = 0;
            while (_CardsChosen.Count < numberCardsToSelect)
            {
                attempts++;
                // Give it 50 attempts at trying to satisfy the Minimum requirements
                if (attempts > 50)
                {
                    throw new ConstraintException("Cannot satisfy specified constraints!  Please double-check and make sure it's possible to construct a Kingdom card setup with the constraints specified.");
                }

                _CardsChosen.Clear();
                _CardsChosen.AddRange(_CardsChosenNeeded);
                Utilities.Shuffler.Shuffle(usableCards);

                foreach (Cards.Card chosenCard in usableCards)
                {
                    if (_CardsChosen.Contains(chosenCard))
                    {
                        continue;
                    }

                    if (this.IsChoosable(_CardsChosen, chosenCard))
                    {
                        _CardsChosen.Add(chosenCard);
                    }

                    if (_CardsChosen.Count == numberCardsToSelect)
                    {
                        break;
                    }
                }
            }

            return(_CardsChosen);
        }