diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs
index 1627833e8a..60898fe92d 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs
@@ -12,9 +12,19 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators
return Math.Tanh(Math.E * -(val - center) / width);
}
- public static double EvaluateDifficultyOf(TaikoDifficultyHitObjectColour colour)
+ public static double EvaluateDifficultyOf(TaikoDifficultyHitObjectColour? colour)
{
- return 1;
+ if (colour == null) return 0;
+
+ double difficulty = 7.5 * Math.Log(colour.Encoding.Payload.Length + 1, 10);
+ // foreach (ColourEncoding encoding in colour.Encoding.Payload)
+ // {
+ // difficulty += sigmoid(encoding.MonoRunLength, 1, 1) * 0.4 + 0.6;
+ // }
+ difficulty *= -sigmoid(colour.RepetitionInterval, 1, 7);
+ // difficulty *= -sigmoid(colour.RepetitionInterval, 2, 2) * 0.5 + 0.5;
+
+ return difficulty;
}
public static double EvaluateDifficultyOf(DifficultyHitObject current)
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs
index be1514891c..9ebdc90eb8 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs
@@ -16,7 +16,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators
/// The interval between the current and previous note hit using the same key.
private static double speedBonus(double interval)
{
- return Math.Pow(0.8, interval / 1000);
+ // return 10 / Math.Pow(interval, 0.6);
+ return Math.Pow(0.1, interval / 1000);
}
///
@@ -40,7 +41,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators
return 0.0;
}
- double objectStrain = 0.85;
+ double objectStrain = 1;
objectStrain *= speedBonus(taikoCurrent.StartTime - keyPrevious.StartTime);
return objectStrain;
}
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/ColourEncoding.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/ColourEncoding.cs
index e2ac40170e..c090e7aada 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/ColourEncoding.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/ColourEncoding.cs
@@ -14,7 +14,12 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
/// Amount of consecutive encoding with the same
///
public int EncodingRunLength = 1;
-
+
+ ///
+ /// How many notes are encoded with this encoding
+ ///
+ public int NoteLength => MonoRunLength + EncodingRunLength;
+
///
/// Beginning index in the data that this encodes
///
@@ -27,7 +32,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
public static List Encode(List data)
{
- // Encoding mono lengths
+ // Compute mono lengths
List firstPass = new List();
ColourEncoding? lastEncoded = null;
for (int i = 0; i < data.Count; i++)
@@ -36,7 +41,11 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
// This ignores all non-note objects, which may or may not be the desired behaviour
TaikoDifficultyHitObject previousObject = (TaikoDifficultyHitObject)taikoObject.PreviousNote(0);
- if (previousObject == null || lastEncoded == null || taikoObject.HitType != previousObject.HitType)
+ if (
+ previousObject == null ||
+ lastEncoded == null ||
+ taikoObject.HitType != previousObject.HitType ||
+ taikoObject.Rhythm.Ratio > 1.9) // Reset colour after a slow down of 2x (set as 1.9x for margin of error)
{
lastEncoded = new ColourEncoding();
lastEncoded.StartIndex = i;
@@ -47,7 +56,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
lastEncoded.MonoRunLength += 1;
}
- // Encode encoding lengths
+ // Compute encoding lengths
List secondPass = new List();
lastEncoded = null;
for (int i = 0; i < firstPass.Count; i++)
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/TaikoDifficultyHitObject.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/TaikoDifficultyHitObject.cs
index 1ee905d94c..7c9188b100 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/TaikoDifficultyHitObject.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/TaikoDifficultyHitObject.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using System.Collections.Generic;
using System.Linq;
@@ -19,7 +17,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
///
public class TaikoDifficultyHitObject : DifficultyHitObject
{
- private readonly IReadOnlyList monoDifficultyHitObjects;
+ private readonly IReadOnlyList? monoDifficultyHitObjects;
public readonly int MonoIndex;
private readonly IReadOnlyList noteObjects;
public readonly int NoteIndex;
@@ -34,7 +32,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
/// by other skills in the future.
/// This need to be writeable by TaikoDifficultyHitObjectColour so that it can assign potentially reused instances
///
- public TaikoDifficultyHitObjectColour Colour;
+ public TaikoDifficultyHitObjectColour? Colour;
///
/// The hit type of this hit object.
@@ -65,14 +63,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
centreObjects, rimObjects, noteObjects, difficultyHitObjects.Count)
);
}
-
- List colours = TaikoDifficultyHitObjectColour.EncodeAndAssign(difficultyHitObjects);
-
- // Pre-evaluate colours
- for (int i = 0; i < colours.Count; i++)
- {
- colours[i].EvaluatedDifficulty = ColourEvaluator.EvaluateDifficultyOf(colours[i]);
- }
+ TaikoDifficultyHitObjectColour.EncodeAndAssign(difficultyHitObjects);
return difficultyHitObjects;
}
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/TaikoDifficultyHitObjectColour.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/TaikoDifficultyHitObjectColour.cs
index 6bd99550be..7e18332fab 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/TaikoDifficultyHitObjectColour.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/TaikoDifficultyHitObjectColour.cs
@@ -5,12 +5,11 @@ using osu.Game.Rulesets.Difficulty.Preprocessing;
namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
{
///
- /// Stores colour compression information for a .
+ /// Stores colour compression information for a . This is only present for the
+ /// first in a chunk.
///
public class TaikoDifficultyHitObjectColour
{
- public CoupledColourEncoding Encoding { get; private set; }
-
private const int max_repetition_interval = 16;
///
@@ -21,11 +20,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
public int RepetitionInterval { get; private set; } = max_repetition_interval + 1;
///
- /// Evaluated colour difficulty is cached here, as difficulty don't need to be calculated per-note.
+ /// Encoding information of .
///
- /// TODO: Consider having all evaluated difficulty cached in TaikoDifficultyHitObject instead, since we may be
- /// reusing evaluator results in the future.
- public double EvaluatedDifficulty = 0;
+ public CoupledColourEncoding Encoding { get; private set; }
public TaikoDifficultyHitObjectColour? Previous { get; private set; } = null;
@@ -60,8 +57,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
}
///
- /// Finds the closest previous that has the identical delta value
- /// and run length with the current instance, and returns the amount of notes between them.
+ /// Finds the closest previous that has the identical .
+ /// Interval is defined as the amount of chunks between the current and repeated encoding.
///
public void FindRepetitionInterval()
{
@@ -72,7 +69,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
}
TaikoDifficultyHitObjectColour? other = Previous.Previous;
- int interval = this.Encoding.StartIndex - other.Encoding.EndIndex;
+ int interval = 2;
while (interval < max_repetition_interval)
{
if (Encoding.hasIdenticalPayload(other.Encoding))
@@ -84,7 +81,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
other = other.Previous;
if (other == null) break;
- interval = this.Encoding.StartIndex - other.Encoding.EndIndex;
+ ++interval;
}
RepetitionInterval = max_repetition_interval + 1;
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Colour.cs b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Colour.cs
index bf359f0d64..c0dafc73b5 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Colour.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Colour.cs
@@ -1,12 +1,12 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
+using System;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Taiko.Difficulty.Preprocessing;
+using osu.Game.Rulesets.Taiko.Difficulty.Evaluators;
namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
{
@@ -18,6 +18,15 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
protected override double SkillMultiplier => 1;
protected override double StrainDecayBase => 0.4;
+ ///
+ /// Applies a speed bonus dependent on the time since the last hit.
+ ///
+ /// The interval between the current and previous note hit using the same key.
+ private static double speedBonus(double interval)
+ {
+ return Math.Pow(0.4, interval / 1000);
+ }
+
public Colour(Mod[] mods)
: base(mods)
{
@@ -25,18 +34,20 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
protected override double StrainValueOf(DifficultyHitObject current)
{
- TaikoDifficultyHitObjectColour colour = ((TaikoDifficultyHitObject)current).Colour;
- double difficulty = colour == null ? 0 : colour.EvaluatedDifficulty;
- // if (current != null && colour != null)
+ double difficulty = ColourEvaluator.EvaluateDifficultyOf(current);
+ // difficulty *= speedBonus(current.DeltaTime);
+ // TaikoDifficultyHitObject? taikoCurrent = (TaikoDifficultyHitObject)current;
+ // TaikoDifficultyHitObjectColour? colour = taikoCurrent?.Colour;
+ // if (taikoCurrent != null && colour != null)
// {
// ColourEncoding[] payload = colour.Encoding.Payload;
// string payloadDisplay = "";
// for (int i = 0; i < payload.Length; ++i)
// {
- // payloadDisplay += $",({payload[i].MonoRunLength},{payload[i].EncodingRunLength})";
+ // payloadDisplay += $",({payload[i].MonoRunLength}|{payload[i].EncodingRunLength})";
// }
- // System.Console.WriteLine($"{current.StartTime},{colour.RepetitionInterval},{colour.Encoding.RunLength}{payloadDisplay}");
+ // System.Console.WriteLine($"{current.StartTime},{difficulty},{colour.RepetitionInterval},{colour.Encoding.RunLength}{payloadDisplay}");
// }
return difficulty;
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Peaks.cs b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Peaks.cs
index ebbe027f9e..7b6fb7d102 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Peaks.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Peaks.cs
@@ -4,17 +4,16 @@ using System.Linq;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills;
using osu.Game.Rulesets.Mods;
-using osu.Game.Rulesets.Taiko.Difficulty.Evaluators;
namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
{
public class Peaks : Skill
{
- private const double rhythm_skill_multiplier = 0.32 * final_multiplier;
- private const double colour_skill_multiplier = 0.33 * final_multiplier;
- private const double stamina_skill_multiplier = 0.4 * final_multiplier;
+ private const double rhythm_skill_multiplier = 0.3 * final_multiplier;
+ private const double colour_skill_multiplier = 0.39 * final_multiplier;
+ private const double stamina_skill_multiplier = 0.33 * final_multiplier;
- private const double final_multiplier = 0.047;
+ private const double final_multiplier = 0.06;
private readonly Rhythm rhythm;
private readonly Colour colour;