1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 17:27:24 +08:00

Remove LegacyDifficultyCalculator

This commit is contained in:
smoogipoo 2019-02-21 13:12:37 +09:00
parent 264fa34c13
commit 7e41fbc29b
14 changed files with 70 additions and 123 deletions

View File

@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Catch.Tests
public void Test(double expected, string name) public void Test(double expected, string name)
=> base.Test(expected, name); => base.Test(expected, name);
protected override LegacyDifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new CatchDifficultyCalculator(new CatchRuleset(), beatmap); protected override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new CatchDifficultyCalculator(new CatchRuleset(), beatmap);
protected override Ruleset CreateRuleset() => new CatchRuleset(); protected override Ruleset CreateRuleset() => new CatchRuleset();
} }

View File

@ -110,7 +110,7 @@ namespace osu.Game.Rulesets.Catch
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o }; public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o };
public override LegacyDifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new CatchDifficultyCalculator(this, beatmap); public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new CatchDifficultyCalculator(this, beatmap);
public override int? LegacyID => 2; public override int? LegacyID => 2;

View File

@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mania.Tests
public void Test(double expected, string name) public void Test(double expected, string name)
=> base.Test(expected, name); => base.Test(expected, name);
protected override LegacyDifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new ManiaDifficultyCalculator(new ManiaRuleset(), beatmap); protected override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new ManiaDifficultyCalculator(new ManiaRuleset(), beatmap);
protected override Ruleset CreateRuleset() => new ManiaRuleset(); protected override Ruleset CreateRuleset() => new ManiaRuleset();
} }

View File

@ -156,7 +156,7 @@ namespace osu.Game.Rulesets.Mania
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o }; public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o };
public override LegacyDifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new ManiaDifficultyCalculator(this, beatmap); public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new ManiaDifficultyCalculator(this, beatmap);
public override int? LegacyID => 3; public override int? LegacyID => 3;

View File

@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Tests
public void Test(double expected, string name) public void Test(double expected, string name)
=> base.Test(expected, name); => base.Test(expected, name);
protected override LegacyDifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new OsuDifficultyCalculator(new OsuRuleset(), beatmap); protected override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new OsuDifficultyCalculator(new OsuRuleset(), beatmap);
protected override Ruleset CreateRuleset() => new OsuRuleset(); protected override Ruleset CreateRuleset() => new OsuRuleset();
} }

View File

@ -133,7 +133,7 @@ namespace osu.Game.Rulesets.Osu
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_osu_o }; public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_osu_o };
public override LegacyDifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new OsuDifficultyCalculator(this, beatmap); public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new OsuDifficultyCalculator(this, beatmap);
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new OsuPerformanceCalculator(this, beatmap, score); public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new OsuPerformanceCalculator(this, beatmap, score);

View File

@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
public void Test(double expected, string name) public void Test(double expected, string name)
=> base.Test(expected, name); => base.Test(expected, name);
protected override LegacyDifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new TaikoDifficultyCalculator(new TaikoRuleset(), beatmap); protected override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new TaikoDifficultyCalculator(new TaikoRuleset(), beatmap);
protected override Ruleset CreateRuleset() => new TaikoRuleset(); protected override Ruleset CreateRuleset() => new TaikoRuleset();
} }

View File

@ -110,7 +110,7 @@ namespace osu.Game.Rulesets.Taiko
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_taiko_o }; public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_taiko_o };
public override LegacyDifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new TaikoDifficultyCalculator(this, beatmap); public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new TaikoDifficultyCalculator(this, beatmap);
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new TaikoPerformanceCalculator(this, beatmap, score); public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new TaikoPerformanceCalculator(this, beatmap, score);

View File

@ -2,9 +2,12 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Collections.Generic;
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Tests.NonVisual namespace osu.Game.Tests.NonVisual
@ -136,7 +139,7 @@ namespace osu.Game.Tests.NonVisual
public override Type[] IncompatibleMods => new[] { typeof(ModA), typeof(ModB) }; public override Type[] IncompatibleMods => new[] { typeof(ModA), typeof(ModB) };
} }
private class TestLegacyDifficultyCalculator : LegacyDifficultyCalculator private class TestLegacyDifficultyCalculator : DifficultyCalculator
{ {
public TestLegacyDifficultyCalculator(params Mod[] mods) public TestLegacyDifficultyCalculator(params Mod[] mods)
: base(null, null) : base(null, null)
@ -146,7 +149,20 @@ namespace osu.Game.Tests.NonVisual
protected override Mod[] DifficultyAdjustmentMods { get; } protected override Mod[] DifficultyAdjustmentMods { get; }
protected override DifficultyAttributes Calculate(IBeatmap beatmap, Mod[] mods, double clockRate) => throw new NotImplementedException(); protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
{
throw new NotImplementedException();
}
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate)
{
throw new NotImplementedException();
}
protected override Skill[] CreateSkills(IBeatmap beatmap)
{
throw new NotImplementedException();
}
} }
} }
} }

View File

@ -54,7 +54,7 @@ namespace osu.Game.Beatmaps
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new DummyBeatmapConverter { Beatmap = beatmap }; public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new DummyBeatmapConverter { Beatmap = beatmap };
public override LegacyDifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => null; public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => null;
public override string Description => "dummy"; public override string Description => "dummy";

View File

@ -4,26 +4,64 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Timing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills; using osu.Game.Rulesets.Difficulty.Skills;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
namespace osu.Game.Rulesets.Difficulty namespace osu.Game.Rulesets.Difficulty
{ {
public abstract class DifficultyCalculator : LegacyDifficultyCalculator public abstract class DifficultyCalculator
{ {
/// <summary> /// <summary>
/// The length of each strain section. /// The length of each strain section.
/// </summary> /// </summary>
protected virtual int SectionLength => 400; protected virtual int SectionLength => 400;
private readonly Ruleset ruleset;
private readonly WorkingBeatmap beatmap;
protected DifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) protected DifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap)
: base(ruleset, beatmap)
{ {
this.ruleset = ruleset;
this.beatmap = beatmap;
} }
protected override DifficultyAttributes Calculate(IBeatmap beatmap, Mod[] mods, double clockRate) /// <summary>
/// Calculates the difficulty of the beatmap using a specific mod combination.
/// </summary>
/// <param name="mods">The mods that should be applied to the beatmap.</param>
/// <returns>A structure describing the difficulty of the beatmap.</returns>
public DifficultyAttributes Calculate(params Mod[] mods)
{
beatmap.Mods.Value = mods;
IBeatmap playableBeatmap = beatmap.GetPlayableBeatmap(ruleset.RulesetInfo);
var clock = new StopwatchClock();
mods.OfType<IApplicableToClock>().ForEach(m => m.ApplyToClock(clock));
return calculate(playableBeatmap, mods, clock.Rate);
}
/// <summary>
/// Calculates the difficulty of the beatmap using all mod combinations applicable to the beatmap.
/// </summary>
/// <returns>A collection of structures describing the difficulty of the beatmap for each mod combination.</returns>
public IEnumerable<DifficultyAttributes> CalculateAll()
{
foreach (var combination in CreateDifficultyAdjustmentModCombinations())
{
if (combination is MultiMod multi)
yield return Calculate(multi.Mods);
else
yield return Calculate(combination);
}
}
private DifficultyAttributes calculate(IBeatmap beatmap, Mod[] mods, double clockRate)
{ {
var skills = CreateSkills(beatmap); var skills = CreateSkills(beatmap);

View File

@ -1,107 +0,0 @@
// 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.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Difficulty
{
public abstract class LegacyDifficultyCalculator
{
private readonly Ruleset ruleset;
private readonly WorkingBeatmap beatmap;
protected LegacyDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap)
{
this.ruleset = ruleset;
this.beatmap = beatmap;
}
/// <summary>
/// Calculates the difficulty of the beatmap using a specific mod combination.
/// </summary>
/// <param name="mods">The mods that should be applied to the beatmap.</param>
/// <returns>A structure describing the difficulty of the beatmap.</returns>
public DifficultyAttributes Calculate(params Mod[] mods)
{
beatmap.Mods.Value = mods;
IBeatmap playableBeatmap = beatmap.GetPlayableBeatmap(ruleset.RulesetInfo);
var clock = new StopwatchClock();
mods.OfType<IApplicableToClock>().ForEach(m => m.ApplyToClock(clock));
return Calculate(playableBeatmap, mods, clock.Rate);
}
/// <summary>
/// Calculates the difficulty of the beatmap using all mod combinations applicable to the beatmap.
/// </summary>
/// <returns>A collection of structures describing the difficulty of the beatmap for each mod combination.</returns>
public IEnumerable<DifficultyAttributes> CalculateAll()
{
foreach (var combination in CreateDifficultyAdjustmentModCombinations())
{
if (combination is MultiMod multi)
yield return Calculate(multi.Mods);
else
yield return Calculate(combination);
}
}
/// <summary>
/// Creates all <see cref="Mod"/> combinations which adjust the <see cref="Beatmap"/> difficulty.
/// </summary>
public Mod[] CreateDifficultyAdjustmentModCombinations()
{
return createDifficultyAdjustmentModCombinations(Enumerable.Empty<Mod>(), DifficultyAdjustmentMods).ToArray();
IEnumerable<Mod> createDifficultyAdjustmentModCombinations(IEnumerable<Mod> currentSet, Mod[] adjustmentSet, int currentSetCount = 0, int adjustmentSetStart = 0)
{
switch (currentSetCount)
{
case 0:
// Initial-case: Empty current set
yield return new ModNoMod();
break;
case 1:
yield return currentSet.Single();
break;
default:
yield return new MultiMod(currentSet.ToArray());
break;
}
// Apply mods in the adjustment set recursively. Using the entire adjustment set would result in duplicate multi-mod mod
// combinations in further recursions, so a moving subset is used to eliminate this effect
for (int i = adjustmentSetStart; i < adjustmentSet.Length; i++)
{
var adjustmentMod = adjustmentSet[i];
if (currentSet.Any(c => c.IncompatibleMods.Any(m => m.IsInstanceOfType(adjustmentMod))))
continue;
foreach (var combo in createDifficultyAdjustmentModCombinations(currentSet.Append(adjustmentMod), adjustmentSet, currentSetCount + 1, i + 1))
yield return combo;
}
}
}
/// <summary>
/// Retrieves all <see cref="Mod"/>s which adjust the <see cref="Beatmap"/> difficulty.
/// </summary>
protected virtual Mod[] DifficultyAdjustmentMods => Array.Empty<Mod>();
/// <summary>
/// Calculates the difficulty of a <see cref="Beatmap"/> using a specific <see cref="Mod"/> combination.
/// </summary>
/// <param name="beatmap">The <see cref="IBeatmap"/> to compute the difficulty for.</param>
/// <param name="mods">The <see cref="Mod"/>s that should be applied.</param>
/// <param name="clockRate">The rate at which the gameplay clock is run at.</param>
/// <returns>A structure containing the difficulty attributes.</returns>
protected abstract DifficultyAttributes Calculate(IBeatmap beatmap, Mod[] mods, double clockRate);
}
}

View File

@ -71,7 +71,7 @@ namespace osu.Game.Rulesets
/// <returns>The <see cref="IBeatmapProcessor"/>.</returns> /// <returns>The <see cref="IBeatmapProcessor"/>.</returns>
public virtual IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => null; public virtual IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => null;
public abstract LegacyDifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap); public abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap);
public virtual PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => null; public virtual PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => null;

View File

@ -44,7 +44,7 @@ namespace osu.Game.Tests.Beatmaps
return Assembly.LoadFrom(Path.Combine(localPath, $"{ResourceAssembly}.dll")).GetManifestResourceStream($@"{ResourceAssembly}.Resources.{name}"); return Assembly.LoadFrom(Path.Combine(localPath, $"{ResourceAssembly}.dll")).GetManifestResourceStream($@"{ResourceAssembly}.Resources.{name}");
} }
protected abstract LegacyDifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap); protected abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap);
protected abstract Ruleset CreateRuleset(); protected abstract Ruleset CreateRuleset();
} }