예제 #1
0
        private void EvaluateArmorSet(IEquipment[] equips, ISolverData data, List <ArmorSetSearchResult> results)
        {
            if (SolverUtils.IsAnyFullArmorSet(equips))
            {
                if (DataUtility.AreOnSameFullArmorSet(equips) == false)
                {
                    searchEquipmentsObjectPool.PutObject(equips);
                    return;
                }
            }

            ArmorSetSearchResult searchResult = IsArmorSetMatching(data.Weapon, equips);

            Interlocked.Increment(ref currentCombinations);

            if (searchResult.IsMatch)
            {
                searchResult.ArmorPieces = new IArmorPiece[]
                {
                    (IArmorPiece)equips[0],
                    (IArmorPiece)equips[1],
                    (IArmorPiece)equips[2],
                    (IArmorPiece)equips[3],
                    (IArmorPiece)equips[4],
                };
                searchResult.Charm = (ICharmLevel)equips[5];

                lock (results)
                    results.Add(searchResult);
            }

            searchEquipmentsObjectPool.PutObject(equips);
        }
예제 #2
0
        public bool TryGetSearchResult(Combination combination, bool hasSuperset, out ArmorSetSearchResult result)
        {
            result = new ArmorSetSearchResult();

            bool skillSummingSuccess = SkillSummingCutoff(combination);

            if (!skillSummingSuccess)
            {
                return(false);
            }

            result.Jewels = new List <ArmorSetJewelResult>();
            int[] totalSlots      = (int[])combination.Slots.Clone();
            int[] remainingLevels = (int[])combination.RemainingSkills.Clone();

            foreach (MappedJewel mappedJewel in combination.Jewels)
            {
                MappedSkill ability    = mappedJewel.Skill;
                int         mappedId   = ability.MappedId;
                int         needLevels = remainingLevels[mappedId];
                if (needLevels <= 0)
                {
                    continue;
                }

                bool jewelSlottingSuccess = TrySlotJewels(mappedJewel, totalSlots, remainingLevels, out ArmorSetJewelResult jewelResult);
                if (!jewelSlottingSuccess)
                {
                    return(false);
                }
                result.Jewels.Add(jewelResult);
            }

            if (hasSuperset)
            {
                bool skillDebtSuccess = SkillDebtCutoff(combination, totalSlots);
                if (!skillDebtSuccess)
                {
                    return(false);
                }
            }

            bool success = remainingLevels.All(x => x <= 0);

            if (!success)
            {
                return(false);
            }

            bool excludedCheckPass = CheckForExcludedSkills(combination);

            if (!excludedCheckPass)
            {
                return(false);
            }

            result.SpareSlots = new int[CutoffSearchConstants.Slots];
            for (int i = 0; i < CutoffSearchConstants.Slots; i++)
            {
                result.SpareSlots[i] = totalSlots[i + 1];
            }

            result.ArmorPieces = new List <IArmorPiece>(CutoffSearchConstants.ArmorTypes);
            for (int i = 0; i < CutoffSearchConstants.ArmorTypes; i++)
            {
                MappedEquipment equipment = combination.Equipments[i];
                if (equipment.Equipment != null)
                {
                    result.ArmorPieces.Add((IArmorPiece)equipment.Equipment);
                }
            }

            result.IsMatch = true;
            result.Charm   = (ICharmLevel)combination.Equipments[CutoffSearchConstants.ArmorTypes].Equipment;
            return(true);
        }
예제 #3
0
        private async Task <IList <ArmorSetSearchResult> > SearchArmorSetsInternal(
            ISolverData data,
            CancellationToken cancellationToken
            )
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(null);
            }

            var allCharms = new List <ICharmLevel>();

            if (cancellationToken.IsCancellationRequested)
            {
                return(null);
            }

            var heads  = new List <IArmorPiece>();
            var chests = new List <IArmorPiece>();
            var gloves = new List <IArmorPiece>();
            var waists = new List <IArmorPiece>();
            var legs   = new List <IArmorPiece>();

            var test = new List <ArmorSetSearchResult>();

            var generator = new EquipmentCombinationGenerator(
                searchEquipmentsObjectPool,
                data.AllHeads.Where(x => x.IsSelected).Select(x => x.Equipment),
                data.AllChests.Where(x => x.IsSelected).Select(x => x.Equipment),
                data.AllGloves.Where(x => x.IsSelected).Select(x => x.Equipment),
                data.AllWaists.Where(x => x.IsSelected).Select(x => x.Equipment),
                data.AllLegs.Where(x => x.IsSelected).Select(x => x.Equipment),
                data.AllCharms.Where(x => x.IsSelected).Select(x => x.Equipment)
                );

            var sb = new StringBuilder();

            long hh = data.AllHeads.Count(x => x.IsSelected);
            long cc = data.AllChests.Count(x => x.IsSelected);
            long gg = data.AllGloves.Count(x => x.IsSelected);
            long ww = data.AllWaists.Count(x => x.IsSelected);
            long ll = data.AllLegs.Count(x => x.IsSelected);
            long ch = data.AllCharms.Count(x => x.IsSelected);

            long combinationCount =
                Math.Max(hh, 1) *
                Math.Max(cc, 1) *
                Math.Max(gg, 1) *
                Math.Max(ww, 1) *
                Math.Max(ll, 1) *
                Math.Max(ch, 1);

            await Task.Yield();

            var parallelOptions = new ParallelOptions
            {
                //MaxDegreeOfParallelism = 1, // to ease debugging
                MaxDegreeOfParallelism = Environment.ProcessorCount
            };

            currentCombinations = 0;
            totalCombinations   = combinationCount;

            ParallelLoopResult parallelResult;

            try
            {
                OrderablePartitioner <IEquipment[]> partitioner = Partitioner.Create(generator.All(cancellationToken), EnumerablePartitionerOptions.NoBuffering);

                parallelResult = Parallel.ForEach(partitioner, parallelOptions, equips =>
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        searchEquipmentsObjectPool.PutObject(equips);
                        return;
                    }

                    ArmorSetSearchResult searchResult = IsArmorSetMatching(data.WeaponSlots, equips, data.AllJewels, data.DesiredAbilities);

                    Interlocked.Increment(ref currentCombinations);

                    if (searchResult.IsMatch)
                    {
                        searchResult.ArmorPieces = new IArmorPiece[]
                        {
                            (IArmorPiece)equips[0],
                            (IArmorPiece)equips[1],
                            (IArmorPiece)equips[2],
                            (IArmorPiece)equips[3],
                            (IArmorPiece)equips[4],
                        };
                        searchResult.Charm = (ICharmLevel)equips[5];

                        lock (test)
                        {
                            test.Add(searchResult);
                        }
                    }

                    searchEquipmentsObjectPool.PutObject(equips);
                });
            }
            finally
            {
                generator.Reset();
            }

            return(test);
        }