Exemple #1
0
        private async Task <IList <ArmorSetSearchResult> > SearchArmorSetsInternal(
            ISolverData data,
            CancellationToken cancellationToken
            )
        {
            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 allCharms = new List <ICharmLevel>();

            var results = 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)
                );

            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
            {
                const int batchSize = 4096;

                using (var equipmentBatchObjectPool = new ObjectPool <EquipmentBatch>(() => EquipmentBatch.Create(batchSize)))
                {
                    OrderablePartitioner <EquipmentBatch> partitioner = Partitioner.Create(generator.AllBatch(equipmentBatchObjectPool, cancellationToken), EnumerablePartitionerOptions.NoBuffering);

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

                        for (int i = 0; i < equipmentBatch.Size; i++)
                        {
                            EvaluateArmorSet(equipmentBatch.Equipment[i], data, results);
                        }

                        equipmentBatchObjectPool.PutObject(equipmentBatch);
                    });
                }
            }
            finally
            {
                generator.Reset();
            }

            return(results);
        }
Exemple #2
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);
        }