예제 #1
0
        public void CompareDifferent()
        {
            var props = new StructFlag <StatsProperty>(StatsProperty.Health);

            var comparer = StatsEffect.CreateComparer(props);

            // Bigger
            var a = new StatsEffect(ChangeType.Add, new Dictionary <StatsProperty, decimal>
            {
                { StatsProperty.Health, 5 }
            });

            // Smaller
            var b = new StatsEffect(ChangeType.Add, new Dictionary <StatsProperty, decimal>
            {
                { StatsProperty.Health, 3 }
            });

            // Bigger first
            Assert.Equal(-1, comparer.Compare(a, b));
            Assert.Equal(-1, StatsEffect.Compare(props, a, b));

            // Smaller first
            Assert.Equal(1, comparer.Compare(b, a));
            Assert.Equal(1, StatsEffect.Compare(props, b, a));
        }
예제 #2
0
        public void CompareDifferentProperties()
        {
            // Bigger by health, smaller by mana, equal by intelligence
            var a = new StatsEffect(ChangeType.Add, new Dictionary <StatsProperty, decimal>
            {
                { StatsProperty.Health, 5 },
                { StatsProperty.Mana, 3 },
                { StatsProperty.Intelligence, 1 }
            });

            // Smaller by health, bigger by mana, equal by intelligence
            var b = new StatsEffect(ChangeType.Add, new Dictionary <StatsProperty, decimal>
            {
                { StatsProperty.Health, 3 },
                { StatsProperty.Mana, 5 },
                { StatsProperty.Intelligence, 1 }
            });

            var health = new StructFlag <StatsProperty>(StatsProperty.Health);

            Assert.Equal(-1, StatsEffect.Compare(health, a, b));

            var mana = new StructFlag <StatsProperty>(StatsProperty.Mana);

            Assert.Equal(1, StatsEffect.Compare(mana, a, b));

            var intelligence = new StructFlag <StatsProperty>(StatsProperty.Intelligence);

            Assert.Equal(0, StatsEffect.Compare(intelligence, a, b));
        }
예제 #3
0
        private bool DetectUseSet(StructFlag <StatsProperty> prop,
                                  IDictionary <ChangeType, MustBeOrderedList <ItemInfo> > items)
        {
            if (items.TryGetValue(ChangeType.Set, out var setItems))
            {
                // Returns is best "set" item better than BaseStats
                return(StatsEffect.Compare(prop, User.Info.BaseStats, TakeBest(1, setItems).First().Item.Effect) == 1);
            }

            return(false);
        }
예제 #4
0
        public void CompareSame()
        {
            var props = new StructFlag <StatsProperty>(StatsProperty.Health);

            var comparer = StatsEffect.CreateComparer(props);

            var a = new StatsEffect(ChangeType.Add, new Dictionary <StatsProperty, decimal>
            {
                { StatsProperty.Health, 5 }
            });
            var b = new StatsEffect(ChangeType.Add, new Dictionary <StatsProperty, decimal>
            {
                { StatsProperty.Health, 5 }
            });

            Assert.Equal(0, comparer.Compare(a, b));
            Assert.Equal(0, StatsEffect.Compare(props, a, b));
        }
예제 #5
0
        private List <ItemInfo> ActivateItems(StructFlag <StatsProperty> prop, MustBeOrderedList <ItemInfo> items)
        {
            if (!ActiveProportions.TryGetValue(prop, out var limit))
            {
                return(new List <ItemInfo>());
            }

            var groups = GroupByChangeType(items);
            var useSet = DetectUseSet(prop, groups);

            var max = limit;

            if (useSet)
            {
                max--;
            }

            var selectedItems = new List <ItemInfo>();

            if (useSet)
            {
                selectedItems.AddRange(TakeBest(1, groups[ChangeType.Set]));
            }

            if (!groups.ContainsKey(ChangeType.Add) && !groups.ContainsKey(ChangeType.Multiply))
            {
                // No multiplication and addition. Only set, maybe.
                // So just do nothing, because DetectUseSet() will handle set.
                return(selectedItems);
            }

            if (!groups.ContainsKey(ChangeType.Add))
            {
                // Only multiplication (and set, maybe)
                selectedItems.AddRange(TakeBest(max, groups[ChangeType.Multiply]));
                return(selectedItems);
            }

            if (!groups.ContainsKey(ChangeType.Multiply))
            {
                // Only addition (and set, maybe)
                selectedItems.AddRange(TakeBest(max, groups[ChangeType.Add]));
                return(selectedItems);
            }

            // Both multiplication and addition (and set, maybe)

            /*
             * Наилучшая комбинация будет если сначала складывать, а потом умножать, т.к. (x + a) * b > (x * b) + a
             * Этот алгоритм сначала пробует взять максимальное количество умножения,
             * потом в каждой итерации добавляет одно сложение. В конце концов пробует только сложения.
             * Работает за O(N^2), где N -- max (ActiveProportions[prop])
             */
            var selectedItemsBase = selectedItems.ToList();
            var bestStats         = User.Info.BaseStats;
            var bestItems         = new List <ItemInfo>();

            for (var addCount = 0; addCount < max; addCount++)
            {
                selectedItems = selectedItemsBase.ToList();

                var mulCount = max - addCount;
                selectedItems.AddRange(TakeBest(addCount, groups[ChangeType.Add]));
                selectedItems.AddRange(TakeBest(mulCount, groups[ChangeType.Multiply]));

                var currentStats = UserInfo.ApplyItems(User.Info.BaseStats, selectedItems);

                if (StatsEffect.Compare(prop, bestStats, currentStats) == 1)
                {
                    bestStats = currentStats;
                    bestItems = selectedItems.ToList();
                }
            }

            return(bestItems);
        }