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); }
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); }
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); }