Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code refactoring Aim and Speed #15485

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
7bb3f06
preskills basecode
GoldenMine0502 Nov 5, 2021
e954294
deleted prestrainskill and changed to skill
GoldenMine0502 Nov 16, 2021
a219974
changed foreach to for
GoldenMine0502 Nov 16, 2021
282f533
minor
GoldenMine0502 Nov 16, 2021
e061a05
add parameter preskills
GoldenMine0502 Nov 21, 2021
152dce0
refactor aim and speed
GoldenMine0502 Dec 11, 2021
74c7cd4
stashed
GoldenMine0502 Dec 11, 2021
5e8674e
merged
GoldenMine0502 Dec 11, 2021
3f41b52
codefactor
GoldenMine0502 Dec 11, 2021
67ab322
fix historylength doesn't work
GoldenMine0502 Dec 11, 2021
b0195f5
fix complexity bonus problem
GoldenMine0502 Dec 11, 2021
31c7cb8
fix unused value
GoldenMine0502 Dec 11, 2021
5080da1
fix unused value
GoldenMine0502 Dec 11, 2021
9ceeee7
codefactor
GoldenMine0502 Dec 11, 2021
457b956
codefactor
GoldenMine0502 Dec 11, 2021
b7d8a00
aim consider first note velocity
GoldenMine0502 Dec 12, 2021
40e208e
license comment
GoldenMine0502 Dec 12, 2021
430bf94
if previous object is spinner cancel calculation
GoldenMine0502 Dec 12, 2021
7e85cf2
changed inheritance of PreStrainSkill from StrainDecaySkill to Strain…
GoldenMine0502 Dec 12, 2021
fdda075
processinternal publicity to protected
GoldenMine0502 Dec 12, 2021
65d19af
codefactor
GoldenMine0502 Dec 12, 2021
3b7f5cb
processinternal changed to internal
GoldenMine0502 Dec 12, 2021
56cfbe3
code quality
GoldenMine0502 Dec 12, 2021
0a6cf86
test case diffcalc-test and zero-length-sliders
GoldenMine0502 Dec 12, 2021
ae49661
code quality
GoldenMine0502 Dec 12, 2021
d8f770f
visiblity processinternal public
GoldenMine0502 Dec 12, 2021
471079d
a
GoldenMine0502 Dec 13, 2021
254a6b3
review
GoldenMine0502 Dec 13, 2021
a840034
code quality
GoldenMine0502 Dec 13, 2021
cfc2a68
code quality
GoldenMine0502 Dec 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clo
};
}

protected override PreStrainSkill[] CreatePreSkills(IBeatmap beatmap, Mod[] mods, double clockRate)
{
return new PreStrainSkill[]
{

};
}

protected override Mod[] DifficultyAdjustmentMods => new Mod[]
{
new CatchModDoubleTime(),
Expand Down
2 changes: 1 addition & 1 deletion osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public Movement(Mod[] mods, float halfCatcherWidth, double clockRate)
catcherSpeedMultiplier = clockRate;
}

protected override double StrainValueOf(DifficultyHitObject current)
protected override double StrainValueOf(PreStrainSkill[] preSkills, int index, DifficultyHitObject current)
{
var catchCurrent = (CatchDifficultyHitObject)current;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(I
new Strain(mods, ((ManiaBeatmap)Beatmap).TotalColumns)
};

protected override PreStrainSkill[] CreatePreSkills(IBeatmap beatmap, Mod[] mods, double clockRate)
{
return new PreStrainSkill[]
{

};
}

protected override Mod[] DifficultyAdjustmentMods
{
get
Expand Down
2 changes: 1 addition & 1 deletion osu.Game.Rulesets.Mania/Difficulty/Skills/Strain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public Strain(Mod[] mods, int totalColumns)
overallStrain = 1;
}

protected override double StrainValueOf(DifficultyHitObject current)
protected override double StrainValueOf(PreStrainSkill[] preSkills, int index, DifficultyHitObject current)
{
var maniaCurrent = (ManiaDifficultyHitObject)current;
double endTime = maniaCurrent.EndTime;
Expand Down
8 changes: 8 additions & 0 deletions osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clo
};
}

protected override PreStrainSkill[] CreatePreSkills(IBeatmap beatmap, Mod[] mods, double clockRate)
{
return new PreStrainSkill[]
{

};
}

protected override Mod[] DifficultyAdjustmentMods => new Mod[]
{
new OsuModDoubleTime(),
Expand Down
7 changes: 4 additions & 3 deletions osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
using osu.Game.Rulesets.Osu.Objects;
Expand All @@ -29,7 +30,7 @@ public Aim(Mod[] mods)
private double skillMultiplier => 23.25;
private double strainDecayBase => 0.15;

private double strainValueOf(DifficultyHitObject current)
private double strainValueOf(PreStrainSkill[] preSkills, int index, DifficultyHitObject current)
{
if (current.BaseObject is Spinner || Previous.Count <= 1 || Previous[0].BaseObject is Spinner)
return 0;
Expand Down Expand Up @@ -110,10 +111,10 @@ private double strainValueOf(DifficultyHitObject current)

protected override double CalculateInitialStrain(double time) => currentStrain * strainDecay(time - Previous[0].StartTime);

protected override double StrainValueAt(DifficultyHitObject current)
protected override double StrainValueAt(PreStrainSkill[] preSkills, int index, DifficultyHitObject current)
{
currentStrain *= strainDecay(current.DeltaTime);
currentStrain += strainValueOf(current) * skillMultiplier;
currentStrain += strainValueOf(preSkills, index, current) * skillMultiplier;

return currentStrain;
}
Expand Down
7 changes: 4 additions & 3 deletions osu.Game.Rulesets.Osu/Difficulty/Skills/Flashlight.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
using osu.Game.Rulesets.Osu.Objects;
Expand All @@ -25,7 +26,7 @@ public Flashlight(Mod[] mods)
protected override int HistoryLength => 10; // Look back for 10 notes is added for the sake of flashlight calculations.
private double currentStrain = 1;

private double strainValueOf(DifficultyHitObject current)
private double strainValueOf(PreStrainSkill[] preSkills, int index, DifficultyHitObject current)
{
if (current.BaseObject is Spinner)
return 0;
Expand Down Expand Up @@ -68,10 +69,10 @@ private double strainValueOf(DifficultyHitObject current)

protected override double CalculateInitialStrain(double time) => currentStrain * strainDecay(time - Previous[0].StartTime);

protected override double StrainValueAt(DifficultyHitObject current)
protected override double StrainValueAt(PreStrainSkill[] preSkills, int index, DifficultyHitObject current)
{
currentStrain *= strainDecay(current.DeltaTime);
currentStrain += strainValueOf(current) * skillMultiplier;
currentStrain += strainValueOf(preSkills, index, current) * skillMultiplier;

return currentStrain;
}
Expand Down
7 changes: 4 additions & 3 deletions osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
using osu.Game.Rulesets.Osu.Objects;
using osu.Framework.Utils;
using osu.Game.Rulesets.Difficulty.Skills;

namespace osu.Game.Rulesets.Osu.Difficulty.Skills
{
Expand Down Expand Up @@ -127,7 +128,7 @@ private double calculateRhythmBonus(DifficultyHitObject current)
return Math.Sqrt(4 + rhythmComplexitySum * rhythm_multiplier) / 2; //produces multiplier that can be applied to strain. range [1, infinity) (not really though)
}

private double strainValueOf(DifficultyHitObject current)
private double strainValueOf(PreStrainSkill[] preSkills, int index, DifficultyHitObject current)
{
if (current.BaseObject is Spinner)
return 0;
Expand Down Expand Up @@ -163,10 +164,10 @@ private double strainValueOf(DifficultyHitObject current)

protected override double CalculateInitialStrain(double time) => (currentStrain * currentRhythm) * strainDecay(time - Previous[0].StartTime);

protected override double StrainValueAt(DifficultyHitObject current)
protected override double StrainValueAt(PreStrainSkill[] preSkills, int index, DifficultyHitObject current)
{
currentStrain *= strainDecay(current.DeltaTime);
currentStrain += strainValueOf(current) * skillMultiplier;
currentStrain += strainValueOf(preSkills, index, current) * skillMultiplier;

currentRhythm = calculateRhythmBonus(current);

Expand Down
2 changes: 1 addition & 1 deletion osu.Game.Rulesets.Taiko/Difficulty/Skills/Colour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public Colour(Mod[] mods)
{
}

protected override double StrainValueOf(DifficultyHitObject current)
protected override double StrainValueOf(PreStrainSkill[] preSkills, int index, DifficultyHitObject current)
{
// changing from/to a drum roll or a swell does not constitute a colour change.
// hits spaced more than a second apart are also exempt from colour strain.
Expand Down
2 changes: 1 addition & 1 deletion osu.Game.Rulesets.Taiko/Difficulty/Skills/Rhythm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public Rhythm(Mod[] mods)
{
}

protected override double StrainValueOf(DifficultyHitObject current)
protected override double StrainValueOf(PreStrainSkill[] preSkills, int index, DifficultyHitObject current)
{
// drum rolls and swells are exempt.
if (!(current.BaseObject is Hit))
Expand Down
2 changes: 1 addition & 1 deletion osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public Stamina(Mod[] mods, bool rightHand)
hand = rightHand ? 1 : 0;
}

protected override double StrainValueOf(DifficultyHitObject current)
protected override double StrainValueOf(PreStrainSkill[] preSkills, int index, DifficultyHitObject current)
{
if (!(current.BaseObject is Hit))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ public TaikoDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap)
new Stamina(mods, false),
};

protected override PreStrainSkill[] CreatePreSkills(IBeatmap beatmap, Mod[] mods, double clockRate)
{
return new PreStrainSkill[]
{

};
}

protected override Mod[] DifficultyAdjustmentMods => new Mod[]
{
new TaikoModDoubleTime(),
Expand Down
30 changes: 28 additions & 2 deletions osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,28 @@ public DifficultyAttributes Calculate(params Mod[] mods)
{
preProcess(mods);

var preSkills = CreatePreSkills(Beatmap, playableMods, clockRate);
var skills = CreateSkills(Beatmap, playableMods, clockRate);

if (!Beatmap.HitObjects.Any())
return CreateDifficultyAttributes(Beatmap, playableMods, skills, clockRate);

int index = 0;
foreach (var hitObject in getDifficultyHitObjects())
{
foreach (var preSkill in preSkills)
preSkill.ProcessInternal(preSkills, index, hitObject);

index++;
}

index = 0;
foreach (var hitObject in getDifficultyHitObjects())
{
foreach (var skill in skills)
skill.ProcessInternal(hitObject);
skill.ProcessInternal(preSkills, index, hitObject);

index++;
}

return CreateDifficultyAttributes(Beatmap, playableMods, skills, clockRate);
Expand All @@ -72,17 +85,29 @@ public List<TimedDifficultyAttributes> CalculateTimed(params Mod[] mods)
if (!Beatmap.HitObjects.Any())
return attribs;

var preSkills = CreatePreSkills(Beatmap, playableMods, clockRate);
var skills = CreateSkills(Beatmap, playableMods, clockRate);
var progressiveBeatmap = new ProgressiveCalculationBeatmap(Beatmap);

int index = 0;
foreach (var hitObject in getDifficultyHitObjects())
{
foreach (var preSkill in preSkills)
preSkill.ProcessInternal(preSkills, index, hitObject);

index++;
}

index = 0;
foreach (var hitObject in getDifficultyHitObjects())
{
progressiveBeatmap.HitObjects.Add(hitObject.BaseObject);

foreach (var skill in skills)
skill.ProcessInternal(hitObject);
skill.ProcessInternal(preSkills, index, hitObject);

attribs.Add(new TimedDifficultyAttributes(hitObject.EndTime * clockRate, CreateDifficultyAttributes(progressiveBeatmap, playableMods, skills, clockRate)));
index++;
}

return attribs;
Expand Down Expand Up @@ -231,6 +256,7 @@ static IEnumerable<Mod> createDifficultyAdjustmentModCombinations(ReadOnlyMemory
/// <param name="clockRate">Clockrate to calculate difficulty with.</param>
/// <returns>The <see cref="Skill"/>s.</returns>
protected abstract Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate);
protected abstract PreStrainSkill[] CreatePreSkills(IBeatmap beatmap, Mod[] mods, double clockRate);

/// <summary>
/// Used to calculate timed difficulty attributes, where only a subset of hitobjects should be visible at any point in time.
Expand Down
74 changes: 74 additions & 0 deletions osu.Game/Rulesets/Difficulty/Skills/PreStrainSkill.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Mods;

namespace osu.Game.Rulesets.Difficulty.Skills
{
public abstract class PreStrainSkill : Skill
{
GoldenMine0502 marked this conversation as resolved.
Show resolved Hide resolved
protected virtual double DecayWeight => 0.9;
protected readonly IBeatmap beatmap;
protected readonly double clockRate;
protected readonly List<double> strainPeaks = new List<double>();

/// <summary>
/// Strain values are multiplied by this number for the given skill. Used to balance the value of different skills between each other.
/// </summary>
protected abstract double SkillMultiplier { get; }
GoldenMine0502 marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Determines how quickly strain decays for the given skill.
/// For example a value of 0.15 indicates that strain decays to 15% of its original value in one second.
/// </summary>
protected abstract double StrainDecayBase { get; }

public PreStrainSkill(IBeatmap beatmap, Mod[] mods, double clockRate) : base(mods)
{
this.beatmap = beatmap;
}

private double currentStrain = 0;

protected override void Process(PreStrainSkill[] preSkills, int index, DifficultyHitObject current)
{
double value = StrainValueOf(preSkills, index, current);

// if the decaybase is smaller than 0, it meant previous notes does not affect next notes
if (StrainDecayBase >= 0.0)
currentStrain *= strainDecay(current.DeltaTime);
else
currentStrain = 0;
currentStrain += value * SkillMultiplier;

strainPeaks.Add(currentStrain);
}

public override double DifficultyValue()
{
double difficulty = 0;
double weight = 1;

// Difficulty is the weighted sum of the highest strains from every section.
// We're sorting from highest to lowest strain.
foreach (double strain in GetAllStrainPeaks().AsEnumerable().OrderByDescending(d => d))
{
difficulty += strain * weight;
weight *= DecayWeight;
}

return difficulty;
}

protected abstract double StrainValueOf(PreStrainSkill[] preSkills, int index, DifficultyHitObject current);
private double strainDecay(double ms) => Math.Pow(StrainDecayBase, ms / 1000);

public List<double> GetAllStrainPeaks()
{
return strainPeaks;
}
}
}
8 changes: 5 additions & 3 deletions osu.Game/Rulesets/Difficulty/Skills/Skill.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,23 @@ protected Skill(Mod[] mods)
Previous = new ReverseQueue<DifficultyHitObject>(HistoryLength + 1);
}

internal void ProcessInternal(DifficultyHitObject current)
internal void ProcessInternal(PreStrainSkill[] preSkills, int index, DifficultyHitObject current)
{
while (Previous.Count > HistoryLength)
Previous.Dequeue();

Process(current);
Process(preSkills, index, current);

Previous.Enqueue(current);
}

/// <summary>
/// Process a <see cref="DifficultyHitObject"/>.
/// </summary>
/// <param name="preSkills"></param>
/// <param name="index"></param>
/// <param name="current">The <see cref="DifficultyHitObject"/> to process.</param>
protected abstract void Process(DifficultyHitObject current);
protected abstract void Process(PreStrainSkill[] preSkills, int index, DifficultyHitObject current);

/// <summary>
/// Returns the calculated difficulty value representing all <see cref="DifficultyHitObject"/>s that have been processed up to this point.
Expand Down
6 changes: 3 additions & 3 deletions osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,18 @@ protected StrainDecaySkill(Mod[] mods)

protected override double CalculateInitialStrain(double time) => CurrentStrain * strainDecay(time - Previous[0].StartTime);

protected override double StrainValueAt(DifficultyHitObject current)
protected override double StrainValueAt(PreStrainSkill[] preSkills, int index, DifficultyHitObject current)
{
CurrentStrain *= strainDecay(current.DeltaTime);
CurrentStrain += StrainValueOf(current) * SkillMultiplier;
CurrentStrain += StrainValueOf(preSkills, index, current) * SkillMultiplier;

return CurrentStrain;
}

/// <summary>
/// Calculates the strain value of a <see cref="DifficultyHitObject"/>. This value is affected by previously processed objects.
/// </summary>
protected abstract double StrainValueOf(DifficultyHitObject current);
protected abstract double StrainValueOf(PreStrainSkill[] preSkills, int index, DifficultyHitObject current);

private double strainDecay(double ms) => Math.Pow(StrainDecayBase, ms / 1000);
}
Expand Down
Loading