diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/RhythmEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/RhythmEvaluator.cs
index 22321a8f6e..8accc6124c 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/RhythmEvaluator.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/RhythmEvaluator.cs
@@ -25,32 +25,32 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators
double samePattern = 0;
double intervalPenalty = 0;
- if (rhythm.SameRhythmHitObjects?.FirstHitObject == hitObject) // Difficulty for SameRhythmHitObjects
+ if (rhythm.SameRhythmGroupedHitObjects?.FirstHitObject == hitObject) // Difficulty for SameRhythmGroupedHitObjects
{
- sameRhythm += 10.0 * evaluateDifficultyOf(rhythm.SameRhythmHitObjects, hitWindow);
- intervalPenalty = repeatedIntervalPenalty(rhythm.SameRhythmHitObjects, hitWindow);
+ sameRhythm += 10.0 * evaluateDifficultyOf(rhythm.SameRhythmGroupedHitObjects, hitWindow);
+ intervalPenalty = repeatedIntervalPenalty(rhythm.SameRhythmGroupedHitObjects, hitWindow);
}
- if (rhythm.SamePatterns?.FirstHitObject == hitObject) // Difficulty for SamePatterns
- samePattern += 1.15 * ratioDifficulty(rhythm.SamePatterns.IntervalRatio);
+ if (rhythm.SamePatternsGroupedHitObjects?.FirstHitObject == hitObject) // Difficulty for SamePatternsGroupedHitObjects
+ samePattern += 1.15 * ratioDifficulty(rhythm.SamePatternsGroupedHitObjects.IntervalRatio);
difficulty += Math.Max(sameRhythm, samePattern) * intervalPenalty;
return difficulty;
}
- private static double evaluateDifficultyOf(SameRhythmHitObjects sameRhythmHitObjects, double hitWindow)
+ private static double evaluateDifficultyOf(SameRhythmGroupedHitObjects sameRhythmGroupedHitObjects, double hitWindow)
{
- double intervalDifficulty = ratioDifficulty(sameRhythmHitObjects.HitObjectIntervalRatio);
- double? previousInterval = sameRhythmHitObjects.Previous?.HitObjectInterval;
+ double intervalDifficulty = ratioDifficulty(sameRhythmGroupedHitObjects.HitObjectIntervalRatio);
+ double? previousInterval = sameRhythmGroupedHitObjects.Previous?.HitObjectInterval;
- intervalDifficulty *= repeatedIntervalPenalty(sameRhythmHitObjects, hitWindow);
+ intervalDifficulty *= repeatedIntervalPenalty(sameRhythmGroupedHitObjects, hitWindow);
// If a previous interval exists and there are multiple hit objects in the sequence:
- if (previousInterval != null && sameRhythmHitObjects.Children.Count > 1)
+ if (previousInterval != null && sameRhythmGroupedHitObjects.Children.Count > 1)
{
- double expectedDurationFromPrevious = (double)previousInterval * sameRhythmHitObjects.Children.Count;
- double durationDifference = sameRhythmHitObjects.Duration - expectedDurationFromPrevious;
+ double expectedDurationFromPrevious = (double)previousInterval * sameRhythmGroupedHitObjects.Children.Count;
+ double durationDifference = sameRhythmGroupedHitObjects.Duration - expectedDurationFromPrevious;
if (durationDifference > 0)
{
@@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators
// Penalise patterns that can be hit within a single hit window.
intervalDifficulty *= DifficultyCalculationUtils.Logistic(
- sameRhythmHitObjects.Duration / hitWindow,
+ sameRhythmGroupedHitObjects.Duration / hitWindow,
midpointOffset: 0.6,
multiplier: 1,
maxValue: 1);
@@ -75,20 +75,20 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators
///
/// Determines if the changes in hit object intervals is consistent based on a given threshold.
///
- private static double repeatedIntervalPenalty(SameRhythmHitObjects sameRhythmHitObjects, double hitWindow, double threshold = 0.1)
+ private static double repeatedIntervalPenalty(SameRhythmGroupedHitObjects sameRhythmGroupedHitObjects, double hitWindow, double threshold = 0.1)
{
- double longIntervalPenalty = sameInterval(sameRhythmHitObjects, 3);
+ double longIntervalPenalty = sameInterval(sameRhythmGroupedHitObjects, 3);
- double shortIntervalPenalty = sameRhythmHitObjects.Children.Count < 6
- ? sameInterval(sameRhythmHitObjects, 4)
+ double shortIntervalPenalty = sameRhythmGroupedHitObjects.Children.Count < 6
+ ? sameInterval(sameRhythmGroupedHitObjects, 4)
: 1.0; // Returns a non-penalty if there are 6 or more notes within an interval.
// The duration penalty is based on hit object duration relative to hitWindow.
- double durationPenalty = Math.Max(1 - sameRhythmHitObjects.Duration * 2 / hitWindow, 0.5);
+ double durationPenalty = Math.Max(1 - sameRhythmGroupedHitObjects.Duration * 2 / hitWindow, 0.5);
return Math.Min(longIntervalPenalty, shortIntervalPenalty) * durationPenalty;
- double sameInterval(SameRhythmHitObjects startObject, int intervalCount)
+ double sameInterval(SameRhythmGroupedHitObjects startObject, int intervalCount)
{
List intervals = new List();
var currentObject = startObject;
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/SameRhythm.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/IntervalGroupedHitObjects.cs
similarity index 62%
rename from osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/SameRhythm.cs
rename to osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/IntervalGroupedHitObjects.cs
index b1ca22595b..930b3fc0e4 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/SameRhythm.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/IntervalGroupedHitObjects.cs
@@ -1,8 +1,8 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using System;
using System.Collections.Generic;
+using osu.Framework.Utils;
namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Rhythm.Data
{
@@ -10,35 +10,26 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Rhythm.Data
/// A base class for grouping s by their interval. In edges where an interval change
/// occurs, the is added to the group with the smaller interval.
///
- public abstract class SameRhythm
- where ChildType : IHasInterval
+ public abstract class IntervalGroupedHitObjects
+ where TChildType : IHasInterval
{
- public IReadOnlyList Children { get; private set; }
+ public IReadOnlyList Children { get; private set; }
///
- /// Determines if the intervals between two child objects are within a specified margin of error,
- /// indicating that the intervals are effectively "flat" or consistent.
- ///
- private bool isFlat(ChildType current, ChildType previous, double marginOfError)
- {
- return Math.Abs(current.Interval - previous.Interval) <= marginOfError;
- }
-
- ///
- /// Create a new from a list of s, and add
+ /// Create a new from a list of s, and add
/// them to the list until the end of the group.
///
/// The list of s.
///
/// Index in to start adding children. This will be modified and should be passed into
- /// the next 's constructor.
+ /// the next 's constructor.
///
///
/// The margin of error for the interval, within of which no interval change is considered to have occured.
///
- protected SameRhythm(List data, ref int i, double marginOfError)
+ protected IntervalGroupedHitObjects(List data, ref int i, double marginOfError)
{
- List children = new List();
+ List children = new List();
Children = children;
children.Add(data[i]);
i++;
@@ -46,9 +37,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Rhythm.Data
for (; i < data.Count - 1; i++)
{
// An interval change occured, add the current data if the next interval is larger.
- if (!isFlat(data[i], data[i + 1], marginOfError))
+ if (!Precision.AlmostEquals(data[i].Interval, data[i + 1].Interval, marginOfError))
{
- if (data[i + 1].Interval > data[i].Interval + marginOfError)
+ if (Precision.DefinitelyBigger(data[i].Interval, data[i + 1].Interval, marginOfError))
{
children.Add(data[i]);
i++;
@@ -63,7 +54,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Rhythm.Data
// Check if the last two objects in the data form a "flat" rhythm pattern within the specified margin of error.
// If true, add the current object to the group and increment the index to process the next object.
- if (data.Count > 2 && isFlat(data[^1], data[^2], marginOfError))
+ if (data.Count > 2 && Precision.AlmostEquals(data[^1].Interval, data[^2].Interval, marginOfError))
{
children.Add(data[i]);
i++;
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/SamePatterns.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/SamePatternsGroupedHitObjects.cs
similarity index 50%
rename from osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/SamePatterns.cs
rename to osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/SamePatternsGroupedHitObjects.cs
index 50839c4561..d4cbc9c1f9 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/SamePatterns.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/SamePatternsGroupedHitObjects.cs
@@ -7,21 +7,21 @@ using System.Linq;
namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Rhythm.Data
{
///
- /// Represents grouped by their 's interval.
+ /// Represents grouped by their 's interval.
///
- public class SamePatterns : SameRhythm
+ public class SamePatternsGroupedHitObjects : IntervalGroupedHitObjects
{
- public SamePatterns? Previous { get; private set; }
+ public SamePatternsGroupedHitObjects? Previous { get; private set; }
///
- /// The between children within this group.
- /// If there is only one child, this will have the value of the first child's .
+ /// The between children within this group.
+ /// If there is only one child, this will have the value of the first child's .
///
public double ChildrenInterval => Children.Count > 1 ? Children[1].Interval : Children[0].Interval;
///
- /// The ratio of between this and the previous . In the
- /// case where there is no previous , this will have a value of 1.
+ /// The ratio of between this and the previous . In the
+ /// case where there is no previous , this will have a value of 1.
///
public double IntervalRatio => ChildrenInterval / Previous?.ChildrenInterval ?? 1.0d;
@@ -29,26 +29,26 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Rhythm.Data
public IEnumerable AllHitObjects => Children.SelectMany(child => child.Children);
- private SamePatterns(SamePatterns? previous, List data, ref int i)
+ private SamePatternsGroupedHitObjects(SamePatternsGroupedHitObjects? previous, List data, ref int i)
: base(data, ref i, 5)
{
Previous = previous;
foreach (TaikoDifficultyHitObject hitObject in AllHitObjects)
{
- hitObject.Rhythm.SamePatterns = this;
+ hitObject.Rhythm.SamePatternsGroupedHitObjects = this;
}
}
- public static void GroupPatterns(List data)
+ public static void GroupPatterns(List data)
{
- List samePatterns = new List();
+ List samePatterns = new List();
- // Index does not need to be incremented, as it is handled within the SameRhythm constructor.
+ // Index does not need to be incremented, as it is handled within the IntervalGroupedHitObjects constructor.
for (int i = 0; i < data.Count;)
{
- SamePatterns? previous = samePatterns.Count > 0 ? samePatterns[^1] : null;
- samePatterns.Add(new SamePatterns(previous, data, ref i));
+ SamePatternsGroupedHitObjects? previous = samePatterns.Count > 0 ? samePatterns[^1] : null;
+ samePatterns.Add(new SamePatternsGroupedHitObjects(previous, data, ref i));
}
}
}
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/SameRhythmHitObjects.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/SameRhythmGroupedHitObjects.cs
similarity index 70%
rename from osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/SameRhythmHitObjects.cs
rename to osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/SameRhythmGroupedHitObjects.cs
index 0ccc6da026..0b59433a2e 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/SameRhythmHitObjects.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/Data/SameRhythmGroupedHitObjects.cs
@@ -9,11 +9,11 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Rhythm.Data
///
/// Represents a group of s with no rhythm variation.
///
- public class SameRhythmHitObjects : SameRhythm, IHasInterval
+ public class SameRhythmGroupedHitObjects : IntervalGroupedHitObjects, IHasInterval
{
public TaikoDifficultyHitObject FirstHitObject => Children[0];
- public SameRhythmHitObjects? Previous;
+ public SameRhythmGroupedHitObjects? Previous;
///
/// of the first hit object.
@@ -26,30 +26,28 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Rhythm.Data
public double Duration => Children[^1].StartTime - Children[0].StartTime;
///
- /// The interval in ms of each hit object in this . This is only defined if there is
- /// more than two hit objects in this .
+ /// The interval in ms of each hit object in this . This is only defined if there is
+ /// more than two hit objects in this .
///
public double? HitObjectInterval;
///
- /// The ratio of between this and the previous . In the
+ /// The ratio of between this and the previous . In the
/// case where one or both of the is undefined, this will have a value of 1.
///
public double HitObjectIntervalRatio = 1;
- ///
- /// The interval between the of this and the previous .
- ///
- public double Interval { get; private set; } = double.PositiveInfinity;
+ ///
+ public double Interval { get; private set; }
- public SameRhythmHitObjects(SameRhythmHitObjects? previous, List data, ref int i)
+ public SameRhythmGroupedHitObjects(SameRhythmGroupedHitObjects? previous, List data, ref int i)
: base(data, ref i, 5)
{
Previous = previous;
foreach (var hitObject in Children)
{
- hitObject.Rhythm.SameRhythmHitObjects = this;
+ hitObject.Rhythm.SameRhythmGroupedHitObjects = this;
// Pass the HitObjectInterval to each child.
hitObject.HitObjectInterval = HitObjectInterval;
@@ -58,15 +56,15 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Rhythm.Data
calculateIntervals();
}
- public static List GroupHitObjects(List data)
+ public static List GroupHitObjects(List data)
{
- List flatPatterns = new List();
+ List flatPatterns = new List();
- // Index does not need to be incremented, as it is handled within SameRhythm's constructor.
+ // Index does not need to be incremented, as it is handled within IntervalGroupedHitObjects's constructor.
for (int i = 0; i < data.Count;)
{
- SameRhythmHitObjects? previous = flatPatterns.Count > 0 ? flatPatterns[^1] : null;
- flatPatterns.Add(new SameRhythmHitObjects(previous, data, ref i));
+ SameRhythmGroupedHitObjects? previous = flatPatterns.Count > 0 ? flatPatterns[^1] : null;
+ flatPatterns.Add(new SameRhythmGroupedHitObjects(previous, data, ref i));
}
return flatPatterns;
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/TaikoDifficultyHitObjectRhythm.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/TaikoDifficultyHitObjectRhythm.cs
index beb7bfe5f6..351015ae08 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/TaikoDifficultyHitObjectRhythm.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Rhythm/TaikoDifficultyHitObjectRhythm.cs
@@ -15,12 +15,12 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Rhythm
///
/// The group of hit objects with consistent rhythm that this object belongs to.
///
- public SameRhythmHitObjects? SameRhythmHitObjects;
+ public SameRhythmGroupedHitObjects? SameRhythmGroupedHitObjects;
///
/// The larger pattern of rhythm groups that this object is part of.
///
- public SamePatterns? SamePatterns;
+ public SamePatternsGroupedHitObjects? SamePatternsGroupedHitObjects;
///
/// The ratio of current