public void ParallelizedDepthFirstSearch(MappedCutoffSearchParameters parameters, int depth, CancellationToken cancellationToken)
 {
     Parallel.ForEach(parameters.AllEquipment[depth], equipment =>
     {
         MappedCutoffSearchParameters parametersCopy = parameters;
         parametersCopy.Combination = new Combination(parameters.Combination);
         parametersCopy.Combination.Replace(depth, equipment);
         DepthFirstSearch(parametersCopy, depth + 1, cancellationToken);
     });
 }
        public void DepthFirstSearch(MappedCutoffSearchParameters parameters, int depth, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested || parameters.Results.Count >= MaxResults)
            {
                return;
            }
            if (depth == parameters.AllEquipment.Length)
            {
                bool match = verifier.TryGetSearchResult(parameters.Combination, false, out ArmorSetSearchResult result);
                parameters.Statistics.RealSearch(match);
                if (match)
                {
                    lock (parameters.Sync)
                    {
                        parameters.Results.Add(result);
                    }
                }
                return;
            }

            bool supersetMatch = verifier.TryGetSearchResult(parameters.Combination, true, out _);

            parameters.Statistics.SupersetSearch(depth, supersetMatch);
            if (!supersetMatch)
            {
                return;
            }

            InvokeProgressChanged(parameters.Statistics.GetCurrentProgress());

            int depthLength = parameters.AllEquipment[depth].Length;

            for (int i = 0; i < depthLength; i++)
            {
                parameters.Combination.Replace(depth, parameters.AllEquipment[depth][i]);
                DepthFirstSearch(parameters, depth + 1, cancellationToken);
            }
            parameters.Combination.Replace(depth, parameters.Supersets[depth]);
        }