public double CalculateDifficulty(DifficultyType type) { var highestStrains = new List <double>(); var intervalEndTime = STRAIN_STEP * _modSpeed; double maximumStrain = 0; TpHitObject previousHitObject = null; foreach (var hitObject in TpHitObjects) { while (hitObject.BaseHitObject.StartTime > intervalEndTime) { highestStrains.Add(maximumStrain); if (previousHitObject == null) { maximumStrain = 0; } else { var decay = Math.Pow(TpHitObject.DECAY_BASE[(int)type], (intervalEndTime - previousHitObject.BaseHitObject.StartTime) / 1000); maximumStrain = previousHitObject.Strains[(int)type] * decay; } intervalEndTime += STRAIN_STEP; } if (hitObject.Strains[(int)type] > maximumStrain) { maximumStrain = hitObject.Strains[(int)type]; } previousHitObject = hitObject; } double difficulty = 0; double weight = 1; highestStrains.Sort((a, b) => b.CompareTo(a)); foreach (var strain in highestStrains) { difficulty += weight * strain; weight *= DECAY_WEIGHT; } return(difficulty); }
private void CalculateSpecificStrain(TpHitObject previousHitObject, DifficultyType type, double speedMultiplier) { double addition = 0; var timeElapsed = (BaseHitObject.StartTime - previousHitObject.BaseHitObject.StartTime) * speedMultiplier; var decay = Math.Pow(DECAY_BASE[(int)type], timeElapsed / 1000); switch (BaseHitObject.Type) { case HitObjectType.Slider: switch (type) { case DifficultyType.Speed: addition = SpacingWeight(previousHitObject._lazySliderLengthFirst + previousHitObject._lazySliderLengthSubsequent * ((previousHitObject.BaseHitObject).SegmentCount - 1) + DistanceTo(previousHitObject), type) * SPACING_WEIGHT_SCALING[(int)type]; break; case DifficultyType.Aim: addition = ( SpacingWeight(previousHitObject._lazySliderLengthFirst, type) + SpacingWeight(previousHitObject._lazySliderLengthSubsequent, type) * ((previousHitObject.BaseHitObject).SegmentCount - 1) + SpacingWeight(DistanceTo(previousHitObject), type) ) * SPACING_WEIGHT_SCALING[(int)type]; break; } break; case HitObjectType.HitCircle: addition = SpacingWeight(DistanceTo(previousHitObject), type) * SPACING_WEIGHT_SCALING[(int)type]; break; } addition /= Math.Max(timeElapsed, 50); Strains[(int)type] = previousHitObject.Strains[(int)type] * decay + addition; }
public double DistanceTo(TpHitObject other) => _normalizedStartPosition.Distance(other._normalizedEndPosition);
public void CalculateStrains(TpHitObject previousHitObject, double speedMultiplier) { CalculateSpecificStrain(previousHitObject, DifficultyType.Speed, speedMultiplier); CalculateSpecificStrain(previousHitObject, DifficultyType.Aim, speedMultiplier); }