Example #1
0
        private static List<Card> AddLands(List<Card> deck, List<Card> library, CardRatings cardRatings)
        {
            var minimalLandCount = DeckCardCount - deck.Count;
              var optimalLandCount = CalculateOptimalLandCount(deck);
              var landCount = Math.Max(minimalLandCount, optimalLandCount);

              var deckSize = landCount + deck.Count;

              if (deckSize > DeckCardCount)
              {
            RemoveWorstCards(
              deck,
              count: deckSize - DeckCardCount,
              cardRatings: cardRatings);
              }

              var distribution = GetLandsDistribution(deck, landCount);

              AddNonBasicLands(distribution, library, deck, cardRatings);

              AddCards("Plains", distribution[0], deck);
              AddCards("Island", distribution[1], deck);
              AddCards("Swamp", distribution[2], deck);
              AddCards("Mountain", distribution[3], deck);
              AddCards("Forest", distribution[4], deck);

              return deck;
        }
Example #2
0
        private static List <Card> TryBuildDeck(List <Card> cards, CardRatings cardRatings)
        {
            var deck = new List <Card>();

            var creatures = cards
                            .Where(x => x.Is().Creature)
                            .OrderByDescending(x => cardRatings.GetRating(x.Name))
                            .ToList();

            var bestCreatures = creatures
                                .Take(MinCreatureCount);

            var otherCreatures = creatures.Skip(MinCreatureCount)
                                 .Take(MaxCreatureCount - MinCreatureCount);

            var spellsAndOtherCreatures = cards
                                          .Where(x => !x.Is().Creature&& !x.Is().Land)
                                          .Concat(otherCreatures)
                                          .OrderByDescending(x => cardRatings.GetRating(x.Name));

            deck.AddRange(bestCreatures);
            deck.AddRange(spellsAndOtherCreatures.Take(MaxSpellCount - deck.Count));


            if (deck.Count < MinSpellCount)
            {
                return(null);
            }


            return(AddLands(deck, cards, cardRatings));
        }
Example #3
0
        private static List <Card> AddLands(List <Card> deck, List <Card> library, CardRatings cardRatings)
        {
            var minimalLandCount = DeckCardCount - deck.Count;
            var optimalLandCount = CalculateOptimalLandCount(deck);
            var landCount        = Math.Max(minimalLandCount, optimalLandCount);

            var deckSize = landCount + deck.Count;

            if (deckSize > DeckCardCount)
            {
                RemoveWorstCards(
                    deck,
                    count: deckSize - DeckCardCount,
                    cardRatings: cardRatings);
            }

            var distribution = GetLandsDistribution(deck, landCount);

            AddNonBasicLands(distribution, library, deck, cardRatings);

            AddCards("Plains", distribution[0], deck);
            AddCards("Island", distribution[1], deck);
            AddCards("Swamp", distribution[2], deck);
            AddCards("Mountain", distribution[3], deck);
            AddCards("Forest", distribution[4], deck);

            return(deck);
        }
Example #4
0
        public static Deck BuildDeck(IEnumerable <CardInfo> library, CardRatings cardRatings)
        {
            var cards = library.Select(x => Cards.All[x.Name])
                        .ToList();

            var candidates = BuildDecks(cards, cardRatings)
                             .Select(x => CreateDeckFromCardList(x, library))
                             .ToList();

            return(DeckEvaluator.GetBestDeck(candidates));
        }
Example #5
0
        private static void RemoveWorstCards(List <Card> deckNoLands, int count, CardRatings cardRatings)
        {
            var cardsToRemove = deckNoLands
                                .OrderBy(x => cardRatings.GetRating(x.Name))
                                .Take(count);

            foreach (var card in cardsToRemove)
            {
                deckNoLands.Remove(card);
            }
        }
Example #6
0
        public static CardRatings Merge(CardRatings ratings1, CardRatings ratings2)
        {
            var result = new CardRatings(ratings1._ratings);

            foreach (var pair in ratings2._ratings)
            {
                result._ratings[pair.Key] = pair.Value;
            }

            return(result);
        }
Example #7
0
        public static CardRatings Merge(CardRatings ratings1, CardRatings ratings2)
        {
            var result = new CardRatings(ratings1._ratings);

              foreach (var pair in ratings2._ratings)
              {
            result._ratings[pair.Key] = pair.Value;
              }

              return result;
        }
Example #8
0
        public static Deck BuildDeck(IEnumerable<CardInfo> library, CardRatings cardRatings)
        {
            var cards = library.Select(x => Cards.All[x.Name])
            .ToList();

              var candidates = BuildDecks(cards, cardRatings)
            .Select(x => CreateDeckFromCardList(x, library))
            .ToList();

              return DeckEvaluator.GetBestDeck(candidates);
        }
Example #9
0
        private static List <Card> AddLands(List <Card> deck, List <Card> library, CardRatings cardRatings,
                                            int landCount)
        {
            var distribution = GetLandsDistribution(deck, landCount);

            AddNonBasicLands(distribution, library, deck, cardRatings);

            AddCards("Plains", distribution[0], deck);
            AddCards("Island", distribution[1], deck);
            AddCards("Swamp", distribution[2], deck);
            AddCards("Mountain", distribution[3], deck);
            AddCards("Forest", distribution[4], deck);

            return(deck);
        }
Example #10
0
        public DraftResults Run(int playerCount, string[] sets, CardRatings ratings)
        {
            var players = CreatePlayers(playerCount, ratings, _userInterface != null);
              var boosters = CreateBoosters(sets, players);

              var round = 1;
              var direction = 1; // clockwise

              while (round <= 3)
              {
            var roundBoosters = boosters
              .Skip((round - 1)*players.Count)
              .Take(players.Count)
              .ToList();

            var cardCount = roundBoosters[0].Count;

            while (cardCount > 0)
            {
              for (var playerIndex = 0; playerIndex < players.Count; playerIndex++)
              {
            var boosterIndex = (100 + playerIndex + direction*cardCount)%players.Count;
            var player = players[playerIndex];

            var draftedCard = player.Strategy.PickCard(roundBoosters[boosterIndex], round);

            if (_userInterface != null && _userInterface.PlayerLeftDraft)
              return null;

            player.Library.Add(draftedCard);
            roundBoosters[boosterIndex].Remove(draftedCard);
              }

              cardCount = roundBoosters[0].Count;
            }

            round++;
            direction = -direction;
              }

              return new DraftResults(players);
        }
Example #11
0
        private static List <List <Card> > BuildDecks(IEnumerable <Card> cards, CardRatings cardRatings)
        {
            var decks = new List <List <Card> >();

            for (var i = CardColor.White; i <= CardColor.Green; i++)
            {
                var cardWithColorI = cards
                                     .Where(x => x.IsMultiColored == false)
                                     .Where(x => x.HasColor(i) || x.HasColor(CardColor.Colorless) || x.Is().Land)
                                     .ToList();

                var monoColoredDeck = TryBuildDeck(cardWithColorI, cardRatings);

                if (monoColoredDeck != null)
                {
                    decks.Add(monoColoredDeck);
                }

                for (var j = i + 1; j <= CardColor.Green; j++)
                {
                    var dual = cards
                               .Where(x => x.HasColor(i) || x.HasColor(j) || x.HasColor(CardColor.Colorless) || x.Is().Land)
                               .ToList();

                    var firstcolorCount  = dual.Count(x => Cards.All[x.Name].HasColor(i));
                    var secondcolorCount = dual.Count(x => Cards.All[x.Name].HasColor(j));

                    if (firstcolorCount >= MinSplashColorCardCount && secondcolorCount >= MinSplashColorCardCount)
                    {
                        var dualDeck = TryBuildDeck(dual, cardRatings);

                        if (dualDeck != null)
                        {
                            decks.Add(dualDeck);
                        }
                    }
                }
            }

            return(decks);
        }
Example #12
0
        private static void AddNonBasicLands(List <int> distribution, List <Card> library, List <Card> deck,
                                             CardRatings cardRatings)
        {
            var nonBasicLands = library.Where(x => x.Is().Land).ToList();
            var deckColors    = distribution.Select((x, i) => x > 0 ? i : -1).Where(x => x >= 0).ToList();
            var maxCountColor = distribution.IndexOf(distribution.Max());

            var landsToReplaceBasic = new List <Card>();

            foreach (var land in nonBasicLands)
            {
                var rating = cardRatings.GetRating(land.Name);
                if (rating < MinNonBasicLandRating)
                {
                    continue;
                }

                var landColors = land.ProducableManaColors;

                if (landColors.Count == 1)
                {
                    if (deckColors.Contains(landColors[0]))
                    {
                        distribution[landColors[0]]--;
                        landsToReplaceBasic.Add(land);
                    }
                }
                else if (landColors.Count > 1)
                {
                    var matchCount = landColors.Count(deckColors.Contains);

                    if (matchCount >= 2)
                    {
                        distribution[maxCountColor]--;
                        landsToReplaceBasic.Add(land);
                    }
                }
            }

            deck.AddRange(landsToReplaceBasic);
        }
Example #13
0
 public static Deck BuildDeck(IEnumerable <CardInfo> library, CardRatings cardRatings)
 {
     return(BuildDeck(library, cardRatings, DeckEvaluator.GetBestDeck));
 }
Example #14
0
        private static void AddNonBasicLands(List<int> distribution, List<Card> library, List<Card> deck,
      CardRatings cardRatings)
        {
            var nonBasicLands = library.Where(x => x.Is().Land).ToList();
              var deckColors = distribution.Select((x, i) => x > 0 ? i : -1).Where(x => x >= 0).ToList();
              var maxCountColor = distribution.IndexOf(distribution.Max());

              var cardsToRemoveCount = 0;
              var landsToReplaceBasic = new List<Card>();

              foreach (var land in nonBasicLands)
              {
            var rating = cardRatings.GetRating(land.Name);
            if (rating < MinNonBasicLandRating)
              continue;

            var landColors = land.ProducableManaColors;

            if (landColors.Count == 0)
            {
              deck.Add(land);
              cardsToRemoveCount++;
            }
            if (landColors.Count == 1)
            {
              if (deckColors.Contains(landColors[0]))
              {
            distribution[landColors[0]]--;
            landsToReplaceBasic.Add(land);
              }
              else if (landColors[0] == (int) CardColor.Colorless)
              {
            if (deckColors.Count > 1)
            {
              deck.Add(land);
              cardsToRemoveCount++;
            }
            else
            {
              distribution[maxCountColor]--;
              landsToReplaceBasic.Add(land);
            }
              }
            }
            else if (landColors.Count > 1)
            {
              var matchCount = landColors.Count(deckColors.Contains);

              if (matchCount >= 2)
              {
            distribution[maxCountColor]--;
            landsToReplaceBasic.Add(land);
              }
            }
              }

              if (cardsToRemoveCount > 0)
              {
            // Some lands do not replace existing lands
            // e.g if they do not produce mana.
            // For each such land remove worst cards from deck
            // so that deck count will be 40.
            RemoveWorstCards(deck, cardsToRemoveCount, cardRatings);
              }

              deck.AddRange(landsToReplaceBasic);
        }
Example #15
0
        private static List<Card> TryBuildDeck(List<Card> cards, CardRatings cardRatings)
        {
            var deck = new List<Card>();

              var creatures = cards
            .Where(x => x.Is().Creature)
            .OrderByDescending(x => cardRatings.GetRating(x.Name))
            .ToList();

              var bestCreatures = creatures
            .Take(MinCreatureCount);

              var otherCreatures = creatures.Skip(MinCreatureCount)
            .Take(MaxCreatureCount - MinCreatureCount);

              var spellsAndOtherCreatures = cards
            .Where(x => !x.Is().Creature && !x.Is().Land)
            .Concat(otherCreatures)
            .OrderByDescending(x => cardRatings.GetRating(x.Name));

              deck.AddRange(bestCreatures);
              deck.AddRange(spellsAndOtherCreatures.Take(MaxSpellCount - deck.Count));

              if (deck.Count < MinSpellCount)
            return null;

              return AddLands(deck, cards, cardRatings);
        }
Example #16
0
        private static void RemoveWorstCards(List<Card> deckNoLands, int count, CardRatings cardRatings)
        {
            var cardsToRemove = deckNoLands
            .OrderBy(x => cardRatings.GetRating(x.Name))
            .Take(count);

              foreach (var card in cardsToRemove)
              {
            deckNoLands.Remove(card);
              }
        }
Example #17
0
        private static List<List<Card>> BuildDecks(IEnumerable<Card> cards, CardRatings cardRatings)
        {
            var decks = new List<List<Card>>();

              for (var i = CardColor.White; i <= CardColor.Green; i++)
              {
            var cardWithColorI = cards
              .Where(x => x.IsMultiColored == false)
              .Where(x => x.HasColor(i) || x.HasColor(CardColor.Colorless) || x.Is().Land)
              .ToList();

            var monoColoredDeck = TryBuildDeck(cardWithColorI, cardRatings);

            if (monoColoredDeck != null)
              decks.Add(monoColoredDeck);

            for (var j = i + 1; j <= CardColor.Green; j++)
            {
              var dual = cards
            .Where(x => x.HasColor(i) || x.HasColor(j) || x.HasColor(CardColor.Colorless) || x.Is().Land)
            .ToList();

              var firstcolorCount = dual.Count(x => Cards.All[x.Name].HasColor(i));
              var secondcolorCount = dual.Count(x => Cards.All[x.Name].HasColor(j));

              if (firstcolorCount >= MinSplashColorCardCount && secondcolorCount >= MinSplashColorCardCount)
              {
            var dualDeck = TryBuildDeck(dual, cardRatings);

            if (dualDeck != null)
              decks.Add(dualDeck);
              }
            }
              }

              return decks;
        }
Example #18
0
        private List<DraftPlayer> CreatePlayers(int playerCount, CardRatings ratings, bool includeHumanPlayer)
        {
            var aiStrategies = new Func<IDraftingStrategy>[]
            {
              () => new Forcing(ratings),
              () => new Greedy(ratings),
            };

              var players = new List<DraftPlayer>();

              for (var i = 0; i < playerCount; i++)
              {
            players.Add(new DraftPlayer
              {
            Strategy = aiStrategies[RandomEx.Next(10) >= 3 ? 0 : 1]()
              });
              }

              if (includeHumanPlayer)
              {
            players[0] = new DraftPlayer
              {
            Strategy = _userInterface
              };
              }

              return players;
        }
Example #19
0
        private static List <List <Card> > BuildDecks(IEnumerable <Card> cards, CardRatings cardRatings)
        {
            var decks = new List <DeckCandidate>();

            for (var i = CardColor.White; i <= CardColor.Green; i++)
            {
                var cardWithColorI = cards
                                     .Where(x => !x.IsMultiColored)
                                     .Where(x => x.HasColor(i) || x.HasColor(CardColor.Colorless) || x.Is().Land)
                                     .ToList();

                var colorCount = cardWithColorI.Count(x => x.HasColor(i));

                if (colorCount > 0)
                {
                    var monoColoredDeck = BuildDeck(cardWithColorI, cardRatings);

                    if (!decks.Any(x => x.Hash == monoColoredDeck.Hash))
                    {
                        decks.Add(monoColoredDeck);
                    }
                }

                for (var j = i + 1; j <= CardColor.Green; j++)
                {
                    var dual = cards
                               .Where(x => x.HasColor(i) || x.HasColor(j) || x.HasColor(CardColor.Colorless) || x.Is().Land)
                               .ToList();

                    var firstcolorCount  = dual.Count(x => Cards.All[x.Name].HasColor(i));
                    var secondcolorCount = dual.Count(x => Cards.All[x.Name].HasColor(j));

                    if (firstcolorCount > 0 && secondcolorCount > 0)
                    {
                        var dualDeck = BuildDeck(dual, cardRatings);

                        if (!decks.Any(x => x.Hash == dualDeck.Hash))
                        {
                            decks.Add(dualDeck);
                        }
                    }
                }
            }

            var playable = decks
                           .Where(x => x.SpellCount == SpellCount)
                           .OrderByDescending(x => x.Rating)
                           .Select(x => x.Cards)
                           .ToList();

            if (playable.Count > 0)
            {
                return(playable);
            }

            var nonPlayable = decks
                              .OrderByDescending(x => x.SpellCount)
                              .Take(1)
                              .Select(x => x.Cards).ToList();

            return(nonPlayable);
        }
Example #20
0
        private static void AddNonBasicLands(List <int> distribution, List <Card> library, List <Card> deck,
                                             CardRatings cardRatings)
        {
            var nonBasicLands = library.Where(x => x.Is().Land).ToList();
            var deckColors    = distribution.Select((x, i) => x > 0 ? i : -1).Where(x => x >= 0).ToList();
            var maxCountColor = distribution.IndexOf(distribution.Max());

            var cardsToRemoveCount  = 0;
            var landsToReplaceBasic = new List <Card>();

            foreach (var land in nonBasicLands)
            {
                var rating = cardRatings.GetRating(land.Name);
                if (rating < MinNonBasicLandRating)
                {
                    continue;
                }

                var landColors = land.ProducableManaColors;

                if (landColors.Count == 0)
                {
                    deck.Add(land);
                    cardsToRemoveCount++;
                }
                if (landColors.Count == 1)
                {
                    if (deckColors.Contains(landColors[0]))
                    {
                        distribution[landColors[0]]--;
                        landsToReplaceBasic.Add(land);
                    }
                    else if (landColors[0] == (int)CardColor.Colorless)
                    {
                        if (deckColors.Count > 1)
                        {
                            deck.Add(land);
                            cardsToRemoveCount++;
                        }
                        else
                        {
                            distribution[maxCountColor]--;
                            landsToReplaceBasic.Add(land);
                        }
                    }
                }
                else if (landColors.Count > 1)
                {
                    var matchCount = landColors.Count(deckColors.Contains);

                    if (matchCount >= 2)
                    {
                        distribution[maxCountColor]--;
                        landsToReplaceBasic.Add(land);
                    }
                }
            }

            if (cardsToRemoveCount > 0)
            {
                // Some lands do not replace existing lands
                // e.g if they do not produce mana.
                // For each such land remove worst cards from deck
                // so that deck count will be 40.
                RemoveWorstCards(deck, cardsToRemoveCount, cardRatings);
            }

            deck.AddRange(landsToReplaceBasic);
        }
Example #21
0
        private static DeckCandidate BuildDeck(List <Card> cards, CardRatings cardRatings)
        {
            var deck = new List <Card>();

            var creatures = cards
                            .Where(x => x.Is().Creature)
                            .Select(x =>
            {
                var convertedCost = x.ConvertedCost;

                if (convertedCost <= 2)
                {
                    convertedCost = 2;
                }

                if (convertedCost >= 6)
                {
                    convertedCost = 6;
                }

                return(new
                {
                    Card = x,
                    ConvertedCost = convertedCost,
                    Rating = cardRatings.GetRating(x.Name)
                });
            })
                            .GroupBy(x => x.ConvertedCost)
                            .OrderBy(x => x.Key)
                            .Select(x =>
            {
                var cost             = x.Key;
                var maxCreatureCount = CreaturesManaCurve[cost - 2];

                var ordered = x.OrderByDescending(y => y.Rating)
                              .ToList();

                var selected = ordered
                               .Take(maxCreatureCount)
                               .Where(y => y.Rating > PlayableThreshold)
                               .Select(y => new { y.Card, y.Rating })
                               .ToList();

                var skipped = ordered
                              .Where(y => !selected.Any(z => z.Card == y.Card))
                              .Select(y => new { y.Card, y.Rating })
                              .ToList();

                return(new
                {
                    Selected = selected,
                    Skipped = skipped
                });
            })
                            .ToList();

            var selectedCreatures = creatures
                                    .SelectMany(x => x.Selected)
                                    .ToList();

            var remaining = creatures
                            .SelectMany(x => x.Skipped)
                            .Concat(cards
                                    .Where(x => !x.Is().Creature&& !x.Is().Land)
                                    .Select(x => new { Card = x, Rating = cardRatings.GetRating(x.Name) }))
                            .OrderByDescending(x => x.Rating)
                            .ToList();


            var selectedRemaining = remaining.
                                    Take(SpellCount - selectedCreatures.Count)
                                    .ToList();

            var avarageRating = selectedCreatures.Concat(selectedRemaining)
                                .Average(x => x.Rating);

            deck.AddRange(selectedCreatures.Select(x => x.Card));
            deck.AddRange(selectedRemaining.Select(x => x.Card));

            var spellCount = deck.Count;

            var landCount = DeckCardCount - spellCount;

            deck = AddLands(deck, cards, cardRatings, landCount);

            return(new DeckCandidate(deck, spellCount, avarageRating));
        }