Ejemplo n.º 1
0
        protected double CalculateDifficulty(DifficultyType type)
        {
            double actualStrainStep = STRAIN_STEP * TimeRate;

            List <double> highestStrains  = new List <double>();
            double        intervalEndTime = actualStrainStep;
            double        maximumStrain   = 0;

            VitaruHitObjectDifficulty previousHitObject = null;

            foreach (VitaruHitObjectDifficulty hitObject in DifficultyHitObjects)
            {
                while (hitObject.BaseHitObject.StartTime > intervalEndTime)
                {
                    highestStrains.Add(maximumStrain);

                    // The maximum strain of the next interval is not zero by default! We need to take the last hitObject we encountered, take its strain and apply the decay
                    // until the beginning of the next interval.
                    if (previousHitObject == null)
                    {
                        maximumStrain = 0;
                    }
                    else
                    {
                        double decay = Math.Pow(VitaruHitObjectDifficulty.DECAY_BASE[(int)type], (intervalEndTime - previousHitObject.BaseHitObject.StartTime) / 1000);
                        maximumStrain = previousHitObject.Strains[(int)type] * decay;
                    }

                    // Go to the next time interval
                    intervalEndTime += actualStrainStep;
                }

                // Obtain maximum strain
                maximumStrain = Math.Max(hitObject.Strains[(int)type], maximumStrain);

                previousHitObject = hitObject;
            }

            // Build the weighted sum over the highest strains for each interval
            double difficulty = 0;
            double weight     = 1;

            highestStrains.Sort((a, b) => b.CompareTo(a)); // Sort from highest to lowest strain.

            foreach (double strain in highestStrains)
            {
                difficulty += weight * strain;
                weight     *= DECAY_WEIGHT;
            }

            return(difficulty);
        }
Ejemplo n.º 2
0
        protected bool CalculateStrainValues()
        {
            // Traverse hitObjects in pairs to calculate the strain value of NextHitObject from the strain value of CurrentHitObject and environment.
            using (List <VitaruHitObjectDifficulty> .Enumerator hitObjectsEnumerator = DifficultyHitObjects.GetEnumerator())
            {
                if (!hitObjectsEnumerator.MoveNext())
                {
                    return(false);
                }

                VitaruHitObjectDifficulty current = hitObjectsEnumerator.Current;

                // First hitObject starts at strain 1. 1 is the default for strain values, so we don't need to set it here. See DifficultyHitObject.
                while (hitObjectsEnumerator.MoveNext())
                {
                    var next = hitObjectsEnumerator.Current;
                    next?.CalculateStrains(current, TimeRate);
                    current = next;
                }

                return(true);
            }
        }