mirror of
https://github.com/ppy/osu.git
synced 2025-01-13 06:32:55 +08:00
[WIP] Colour evaluator for new colour encoding
This commit is contained in:
parent
55e5b41c03
commit
cba47f8202
@ -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)
|
||||
|
@ -16,7 +16,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators
|
||||
/// <param name="interval">The interval between the current and previous note hit using the same key.</param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -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;
|
||||
}
|
||||
|
@ -15,6 +15,11 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
|
||||
/// </summary>
|
||||
public int EncodingRunLength = 1;
|
||||
|
||||
/// <summary>
|
||||
/// How many notes are encoded with this encoding
|
||||
/// </summary>
|
||||
public int NoteLength => MonoRunLength + EncodingRunLength;
|
||||
|
||||
/// <summary>
|
||||
/// Beginning index in the data that this encodes
|
||||
/// </summary>
|
||||
@ -27,7 +32,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
|
||||
|
||||
public static List<ColourEncoding> Encode(List<DifficultyHitObject> data)
|
||||
{
|
||||
// Encoding mono lengths
|
||||
// Compute mono lengths
|
||||
List<ColourEncoding> firstPass = new List<ColourEncoding>();
|
||||
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<ColourEncoding> secondPass = new List<ColourEncoding>();
|
||||
lastEncoded = null;
|
||||
for (int i = 0; i < firstPass.Count; i++)
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. 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
|
||||
/// </summary>
|
||||
public class TaikoDifficultyHitObject : DifficultyHitObject
|
||||
{
|
||||
private readonly IReadOnlyList<TaikoDifficultyHitObject> monoDifficultyHitObjects;
|
||||
private readonly IReadOnlyList<TaikoDifficultyHitObject>? monoDifficultyHitObjects;
|
||||
public readonly int MonoIndex;
|
||||
private readonly IReadOnlyList<TaikoDifficultyHitObject> 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
|
||||
/// </summary>
|
||||
public TaikoDifficultyHitObjectColour Colour;
|
||||
public TaikoDifficultyHitObjectColour? Colour;
|
||||
|
||||
/// <summary>
|
||||
/// The hit type of this hit object.
|
||||
@ -65,14 +63,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
|
||||
centreObjects, rimObjects, noteObjects, difficultyHitObjects.Count)
|
||||
);
|
||||
}
|
||||
|
||||
List<TaikoDifficultyHitObjectColour> 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;
|
||||
}
|
||||
|
@ -5,12 +5,11 @@ using osu.Game.Rulesets.Difficulty.Preprocessing;
|
||||
namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores colour compression information for a <see cref="TaikoDifficultyHitObject"/>.
|
||||
/// Stores colour compression information for a <see cref="TaikoDifficultyHitObject"/>. This is only present for the
|
||||
/// first <see cref="TaikoDifficultyHitObject"/> in a <see cref="CoupledColourEncoding"/> chunk.
|
||||
/// </summary>
|
||||
public class TaikoDifficultyHitObjectColour
|
||||
{
|
||||
public CoupledColourEncoding Encoding { get; private set; }
|
||||
|
||||
private const int max_repetition_interval = 16;
|
||||
|
||||
/// <summary>
|
||||
@ -21,11 +20,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
|
||||
public int RepetitionInterval { get; private set; } = max_repetition_interval + 1;
|
||||
|
||||
/// <summary>
|
||||
/// Evaluated colour difficulty is cached here, as difficulty don't need to be calculated per-note.
|
||||
/// Encoding information of <see cref="TaikoDifficultyHitObjectColour"/>.
|
||||
/// </summary>
|
||||
/// 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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the closest previous <see cref="TaikoDifficultyHitObjectColour"/> 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 <see cref="TaikoDifficultyHitObjectColour"/> that has the identical <see cref="CoupledColourEncoding.Payload"/>.
|
||||
/// Interval is defined as the amount of <see cref="CoupledColourEncoding"/> chunks between the current and repeated encoding.
|
||||
/// </summary>
|
||||
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;
|
||||
|
@ -1,12 +1,12 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. 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;
|
||||
|
||||
/// <summary>
|
||||
/// Applies a speed bonus dependent on the time since the last hit.
|
||||
/// </summary>
|
||||
/// <param name="interval">The interval between the current and previous note hit using the same key.</param>
|
||||
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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user