예제 #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);
 }
예제 #2
0
        public ItemSet(string title = "")
        {
            this.SetKey     = null;
            this.MatchCount = 0;

            this.title       = title;
            this.description = "";
            this.type        = Type.Custom;
            this.map         = Map.any;
            this.mode        = Mode.any;
            this.priority    = false;
            this.sortrank    = 0;
            this.blocks      = null;
        }
예제 #3
0
        public static ItemSet generate(PurchaseSetKey setKey, ChampionPurchaseCalculator stats)
        {
            //Lookup the champion
            var championKey = StaticDataStore.Champions.Keys[setKey.ChampionId];
            var championInfo = StaticDataStore.Champions.Champions[championKey];

            // Create the set and key it
            ItemSet itemSet = new ItemSet();
            itemSet.SetKey = setKey;
            itemSet.MatchCount = stats.MatchCount;

            //Come up with an item set title
            itemSet.title = championInfo.Name + " " + ItemSetNaming.ToolName;

            //Add a nice description of how this was generated
            itemSet.description = "Pro item set generated using " + stats.MatchCount.ToString() + " challenger/master matches.";

            //Fill out a bunch of other stuff that is the same for this tool
            itemSet.type = type;
            itemSet.map = map;
            itemSet.mode = mode;
            itemSet.priority = priority;
            itemSet.sortrank = sortRank < 0 ? 0 : sortRank;

            // Block info
            var blockData = new[]
            {
                new { Name = "Starting Items", Stage = GameStage.Start },
                new { Name = "Early Items", Stage = GameStage.Early },
                new { Name = "Midgame Items", Stage = GameStage.Mid },
                new { Name = "Lategame Items", Stage = GameStage.Late }
            };

            // Create blocks and filter to non-empty blocks
            var blocks = blockData
                .Where(blockInfo => stats.Purchases.ContainsKey(blockInfo.Stage))
                .Select(blockInfo =>
                new ItemSet.Block(blockInfo.Name)
                {
                    items = stats.Purchases[blockInfo.Stage].Select(entry => new ItemSet.Item(entry.ItemId.ToString())
                    {
                        count = 1,
                        percentage = entry.Percentage
                    }).ToList()
                })
                .Where(block => block.items.Count > 0).ToList();

            // Combine adjacent items
            blocks.ForEach(block =>
            {
                for (int i = 0; i < block.items.Count - 1; ++i)
                {
                    if (block.items[i].id == block.items[i + 1].id)
                    {
                        // Remove when adjacent, and keep the lower percentage
                        block.items[i].count = block.items[i].count + 1;
                        block.items.RemoveAt(i+1);
                        --i;
                    }
                }
            });

            // Add blocks to item set
            itemSet.blocks = blocks;

            return itemSet;
        }
예제 #4
0
        public static ItemSet generate(PurchaseSetKey setKey, ChampionPurchaseCalculator stats)
        {
            //Lookup the champion
            var championKey  = StaticDataStore.Champions.Keys[setKey.ChampionId];
            var championInfo = StaticDataStore.Champions.Champions[championKey];

            // Create the set and key it
            ItemSet itemSet = new ItemSet();

            itemSet.SetKey     = setKey;
            itemSet.MatchCount = stats.MatchCount;

            //Come up with an item set title
            itemSet.title = championInfo.Name + " " + ItemSetNaming.ToolName;

            //Add a nice description of how this was generated
            itemSet.description = "Pro item set generated using " + stats.MatchCount.ToString() + " challenger/master matches.";

            //Fill out a bunch of other stuff that is the same for this tool
            itemSet.type     = type;
            itemSet.map      = map;
            itemSet.mode     = mode;
            itemSet.priority = priority;
            itemSet.sortrank = sortRank < 0 ? 0 : sortRank;

            // Block info
            var blockData = new[]
            {
                new { Name = "Starting Items", Stage = GameStage.Start },
                new { Name = "Early Items", Stage = GameStage.Early },
                new { Name = "Midgame Items", Stage = GameStage.Mid },
                new { Name = "Lategame Items", Stage = GameStage.Late }
            };

            // Create blocks and filter to non-empty blocks
            var blocks = blockData
                         .Where(blockInfo => stats.Purchases.ContainsKey(blockInfo.Stage))
                         .Select(blockInfo =>
                                 new ItemSet.Block(blockInfo.Name)
            {
                items = stats.Purchases[blockInfo.Stage].Select(entry => new ItemSet.Item(entry.ItemId.ToString())
                {
                    count      = 1,
                    percentage = entry.Percentage
                }).ToList()
            })
                         .Where(block => block.items.Count > 0).ToList();

            // Combine adjacent items
            blocks.ForEach(block =>
            {
                for (int i = 0; i < block.items.Count - 1; ++i)
                {
                    if (block.items[i].id == block.items[i + 1].id)
                    {
                        // Remove when adjacent, and keep the lower percentage
                        block.items[i].count = block.items[i].count + 1;
                        block.items.RemoveAt(i + 1);
                        --i;
                    }
                }
            });

            // Add blocks to item set
            itemSet.blocks = blocks;

            return(itemSet);
        }
        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));
            }
        }