Exemplo n.º 1
0
        /// <summary>
        /// Track purchases for this champion.
        /// </summary>
        public void Process(ChampionMatchItemPurchases matchPurchases)
        {
            // Create or get the purchase set for this match
            PurchaseSetKey key = new PurchaseSetKey(matchPurchases);
            PurchaseSet    set = PurchaseSets.GetOrAdd(key, k => new PurchaseSet(k));

            set.Process(matchPurchases);
        }
Exemplo n.º 2
0
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(this, obj))
            {
                return(true);
            }

            if (obj == null)
            {
                return(true);
            }

            if (!(obj is PurchaseSetKey))
            {
                return(false);
            }

            PurchaseSetKey other = obj as PurchaseSetKey;

            return
                (ChampionId == other.ChampionId &&
                 Lane == other.Lane &&
                 HasSmite == other.HasSmite);
        }
Exemplo n.º 3
0
 public PurchaseSet(PurchaseSetKey key)
 {
     Key = key;
 }
Exemplo n.º 4
0
        public ChampionPurchaseCalculator(PurchaseSet set)
        {
            Key = set.Key;

            MatchCount = set.MatchCount;

            // Create stats
            var stats = PurchaseStats.Create(set.AllItemPurchases, set.MatchCount);

            // Compute initial determinations based on game stage and settings percentages
            var statsList = stats.SelectMany(kvp => kvp.Value.Select(nkvp => nkvp.Value));
            var purchaseDeterminations = statsList.Select(purchaseStats => new IncludeDetermination()
            {
                Stats     = purchaseStats,
                GameStage = SetBuilderSettings.GetGameStage(purchaseStats),
                Include   = false
            }).ToDictionary(
                determination => new ItemPurchaseTrackerData.ItemPurchaseKey(determination.Stats)
                );

            // Filter initial include list by percentage
            purchaseDeterminations.Values
            .Where(determination => determination.Stats.Percentage >= SetBuilderSettings.ItemMinimumPurchasePercentage[determination.GameStage])
            .ToList()
            .ForEach(determination => determination.Include = true);

            // Compute build path includes
            DetermineBuildPathIncludes(purchaseDeterminations);

            // Generate stage-based include list
            Purchases = purchaseDeterminations.Values
                        .Where(determination => determination.Include)
                        .GroupBy(determination => determination.GameStage)
                        .ToDictionary(
                g => g.Key,
                g => g.Select(d => d.Stats).OrderBy(s => s.AveragePurchaseTimeSeconds).ToList()
                );

            // If early items contain items that build into a mid-game item, migrate the mid-game item to early game
            if (Purchases.ContainsKey(GameStage.Early) && Purchases.ContainsKey(GameStage.Mid))
            {
                // Check if a full build path exists in the early stage already
                bool hasFullEarlyPath = Purchases[GameStage.Early].Any(p =>
                                                                       p.FinalBuildItemPercentage.Any(finalItem => Purchases[GameStage.Early].Any(i => finalItem.Key.ItemId == i.ItemId)));

                if (!hasFullEarlyPath)
                {
                    // Find the first early game item that builds into something in mid-game
                    var earlyItem = Purchases[GameStage.Early].FirstOrDefault(p =>
                                                                              p.FinalBuildItemPercentage.Any(finalItem => Purchases[GameStage.Mid].Any(i => finalItem.Key.ItemId == i.ItemId)));

                    if (earlyItem != null)
                    {
                        // Find the mid-game item to move
                        var midItemIndex = Purchases[GameStage.Mid].FindIndex(i => earlyItem.FinalBuildItemPercentage.Any(kvp => kvp.Key.ItemId == i.ItemId));
                        var midItem      = Purchases[GameStage.Mid][midItemIndex];

                        // Move the mid-game item
                        Purchases[GameStage.Early].Add(midItem);
                        Purchases[GameStage.Mid].RemoveAt(midItemIndex);
                    }
                }
            }

            // If start items add up to less than 475, try to absorb first early item
            if (Purchases.ContainsKey(GameStage.Start) && Purchases.ContainsKey(GameStage.Early))
            {
                int startCost = Purchases[GameStage.Start].Sum(d => StaticDataStore.Items.Items[d.ItemId].Gold.TotalPrice);
                if (startCost < 475)
                {
                    ItemPurchaseStats d = Purchases[GameStage.Early].FirstOrDefault();
                    if (StaticDataStore.Items.Items[d.ItemId].Gold.TotalPrice + startCost <= 475)
                    {
                        // Move item
                        Purchases[GameStage.Start].Add(d);
                        Purchases[GameStage.Early].RemoveAt(0);
                    }
                }
            }

            // Move consumables to end of each section
            foreach (GameStage stage in Purchases.Keys)
            {
                // Remove all consumables, sort by cost, then add to end of list
                var purchaseList = Purchases[stage];
                var consumables  = purchaseList.Where(d => StaticDataStore.Items.Items[d.ItemId].Consumed).ToList();
                purchaseList.RemoveAll(d => consumables.Contains(d));
                consumables.Sort((a, b) =>
                {
                    int cmp = StaticDataStore.Items.Items[a.ItemId].Gold.TotalPrice.CompareTo(
                        StaticDataStore.Items.Items[b.ItemId].Gold.TotalPrice);

                    if (cmp != 0)
                    {
                        return(cmp);
                    }

                    return(a.ItemId.CompareTo(b.ItemId));
                }
                                 );
                purchaseList.AddRange(consumables);
            }

            // Remove components in mid/late game
            var removeComponentsStages = new[] { GameStage.Late, GameStage.Mid };
            IEnumerable <ItemStatic> componentItems = Enumerable.Empty <ItemStatic>();

            foreach (GameStage stage in removeComponentsStages)
            {
                if (!Purchases.ContainsKey(stage))
                {
                    continue;
                }

                var allComponents = Purchases[stage]
                                    .Select(p => StaticDataStore.Items.Items[p.ItemId])
                                    .Where(i => i.Into == null || i.Into.Count == 0)
                                    .SelectMany(i => i.AllComponents())
                                    .Where(i => i.Tags == null || (!i.Tags.Contains("Boots") && !i.Tags.Contains("Trinket")))
                                    .Distinct();

                componentItems = componentItems.Concat(allComponents).Distinct().ToList();

                // Remove any component items
                Purchases[stage].RemoveAll(i => componentItems.Any(c => c.Id == i.ItemId));
            }
        }