diff --git a/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs new file mode 100644 index 0000000000..b8b5e3bb36 --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs @@ -0,0 +1,32 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Diagnostics; +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Difficulty; +using osu.Game.Rulesets.Osu.Difficulty; +using osu.Game.Tests.Beatmaps; + +namespace osu.Game.Rulesets.Osu.Tests +{ + [TestFixture] + public class OsuDifficultyCalculatorTest : DifficultyCalculatorTest + { + protected override string ResourceAssembly => "osu.Game.Rulesets.Osu"; + + [Test] + public new void Test() + { + base.Test(6.9311449688341344, "diffcalc-test"); + } + + private void openUsingShellExecute(string path) => Process.Start(new ProcessStartInfo + { + FileName = path, + UseShellExecute = true //see https://github.com/dotnet/corefx/issues/10361 + }); + + protected override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new OsuDifficultyCalculator(new OsuRuleset(), beatmap); + } +} diff --git a/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/diffcalc-test.osu b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/diffcalc-test.osu new file mode 100644 index 0000000000..4b42cd4ffd --- /dev/null +++ b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/diffcalc-test.osu @@ -0,0 +1,167 @@ +osu file format v14 + +[General] +StackLeniency: 0.3 +Mode: 0 + +[Difficulty] +CircleSize:4 +OverallDifficulty:7 +ApproachRate:8.3 +SliderMultiplier:1.6 +SliderTickRate:1 + +[TimingPoints] +500,500,4,2,1,50,1,0 +62500,-500,4,2,1,50,0,0 +71000,-100,4,2,1,50,0,0 + +[HitObjects] +// Circles spaced 1 beat apart, with increasing jump distance +126,112,500,5,0,0:0:0:0: +130,155,1000,1,0,0:0:0:0: +131,269,1500,1,0,0:0:0:0: +341,269,2000,1,0,0:0:0:0: +113,95,2500,1,0,0:0:0:0: + +// Circles spaced 1/2 beat apart, with increasing jump distance +108,104,3500,5,0,0:0:0:0: +110,145,3750,1,0,0:0:0:0: +115,262,4000,1,0,0:0:0:0: +285,265,4250,1,0,0:0:0:0: +458,48,4500,1,0,0:0:0:0: +35,199,4750,1,0,0:0:0:0: +251,340,5000,1,0,0:0:0:0: +20,352,5250,1,0,0:0:0:0: +426,62,5500,1,0,0:0:0:0: + +// Circles spaced 1/4 beat apart, with increasing jump distances +211,138,6500,5,0,0:0:0:0: +99,256,6625,1,0,0:0:0:0: +68,129,6750,1,0,0:0:0:0: +371,340,6875,1,0,0:0:0:0: +241,219,7000,1,0,0:0:0:0: +252,148,7125,1,0,0:0:0:0: +434,97,7250,1,0,0:0:0:0: +40,38,7375,1,0,0:0:0:0: +114,334,7500,1,0,0:0:0:0: +301,19,7625,1,0,0:0:0:0: +441,241,7750,1,0,0:0:0:0: +121,91,7875,1,0,0:0:0:0: +270,384,8000,1,0,0:0:0:0: +488,92,8125,1,0,0:0:0:0: +332,82,8250,1,0,0:0:0:0: +108,240,8375,1,0,0:0:0:0: +281,268,8500,1,0,0:0:0:0: + +// Constant spaced circles spaced 1/2 beat apart, small jump distances, changing angles +252,191,9500,5,0,0:0:0:0: +356,191,9750,1,0,0:0:0:0: +311,268,10000,1,0,0:0:0:0: +190,270,10250,1,0,0:0:0:0: +107,199,10500,1,0,0:0:0:0: +172,105,10750,1,0,0:0:0:0: +297,102,11000,1,0,0:0:0:0: +373,178,11250,1,0,0:0:0:0: +252,195,11500,1,0,0:0:0:0: + +// Constant spaced circles spaced 1/2 beat apart, large jump distances, changing angles +140,187,12500,5,0,0:0:0:0: +451,331,12750,1,0,0:0:0:0: +46,338,13000,1,0,0:0:0:0: +204,50,13250,1,0,0:0:0:0: +464,162,13500,1,0,0:0:0:0: +252,346,13750,1,0,0:0:0:0: +13,175,14000,1,0,0:0:0:0: +488,181,14250,1,0,0:0:0:0: +251,187,14500,1,0,0:0:0:0: + +// Constant spaced circles spaced 1/4 beat apart, small jump distances, changing angles +188,192,15500,5,0,0:0:0:0: +298,194,15625,1,0,0:0:0:0: +317,84,15750,1,0,0:0:0:0: +185,85,15875,1,0,0:0:0:0: +77,200,16000,1,0,0:0:0:0: +184,303,16125,1,0,0:0:0:0: +295,225,16250,1,0,0:0:0:0: +300,84,16375,1,0,0:0:0:0: +144,82,16500,1,0,0:0:0:0: +141,215,16625,1,0,0:0:0:0: +314,184,16750,1,0,0:0:0:0: +188,192,16875,1,0,0:0:0:0: +188,192,17000,1,0,0:0:0:0: + +// Constant spaced circles spaced 1/4 beat apart, large jump distances, changing angles +97,192,18000,5,0,0:0:0:0: +336,38,18125,1,0,0:0:0:0: +440,322,18250,1,0,0:0:0:0: +39,331,18375,1,0,0:0:0:0: +98,39,18500,1,0,0:0:0:0: +460,179,18625,1,0,0:0:0:0: +245,338,18750,1,0,0:0:0:0: +12,184,18875,1,0,0:0:0:0: +250,41,19000,1,0,0:0:0:0: +265,193,19125,1,0,0:0:0:0: +486,22,19250,1,0,0:0:0:0: +411,205,19375,1,0,0:0:0:0: +107,198,19500,1,0,0:0:0:0: + +// Short sliders spaced 1 beat apart +28,108,20500,2,0,L|196:107,1,160 +25,177,21500,2,0,L|193:176,1,160 +26,308,22500,2,0,L|194:307,1,160 +320,89,23500,2,0,L|488:88,1,160 + +// Short sliders spaced 1/2 beat apart +28,108,25000,6,0,L|196:107,1,160 +27,173,25750,2,0,L|195:172,1,160 +25,292,26500,2,0,L|193:291,1,160 +340,213,27250,2,0,L|508:212,1,160 +21,44,28000,2,0,L|189:43,1,160 + +// Short sliders spaced 1/4 beat apart +28,108,29500,6,0,L|196:107,1,160 +30,169,30125,2,0,L|198:168,1,160 +35,282,30750,2,0,L|203:281,1,160 +327,286,31375,2,0,L|495:285,1,160 +51,61,32000,2,0,L|219:60,1,160 + +// Large, medium-paced slider shapes +// PerfectCurve +66,86,33500,6,0,P|246:348|427:44,1,800 +66,86,36500,2,0,P|246:348|427:44,1,800 +66,86,39500,2,0,P|246:348|427:44,1,800 +// Linear +66,72,42500,2,0,B|419:65|419:65|66:316|66:316|426:318,1,1120 +66,72,46500,2,0,B|419:65|419:65|66:316|66:316|426:318,1,1120 +66,72,50500,2,0,B|419:65|419:65|66:316|66:316|426:318,1,1120 +// Bezier +76,287,54500,2,0,B|440:325|138:128|470:302|500:30|130:85|66:82,1,640 +76,287,57000,2,0,B|440:325|138:128|470:302|500:30|130:85|66:82,1,640 +76,287,59500,2,0,B|440:325|138:128|470:302|500:30|130:85|66:82,1,640 + +// Large slow slider with many ticks +81,170,62500,6,0,P|263:78|168:268,1,480 + +// Fast slider with many repeats +102,152,71000,6,0,L|175:153,18,64 + +// Slider-circle combos, spaced 1/2 beat apart +106,204,75500,6,0,P|275:33|171:304,1,800 +255,179,78250,1,0,0:0:0:0: +106,204,78500,2,0,P|275:33|171:304,1,800 +255,179,81250,1,0,0:0:0:0: +106,204,81500,2,0,P|275:33|171:304,1,800 + +// Circle-spinner combos, spaced 1/2 beat apart +82,69,85000,5,0,0:0:0:0: +256,192,85250,8,0,86000,0:0:0:0: +83,69,86250,5,0,0:0:0:0: +256,192,86500,12,0,87000,0:0:0:0: + +// Spinner-spinner combos, spaced 1/2 beat apart +256,192,88000,12,0,89000,0:0:0:0: +256,192,89250,12,0,90250,0:0:0:0: +256,192,90500,12,0,91500,0:0:0:0: +256,192,91750,12,0,92750,0:0:0:0: +256,192,93000,12,0,94000,0:0:0:0: diff --git a/osu.Game/Tests/Beatmaps/DifficultyCalculatorTest.cs b/osu.Game/Tests/Beatmaps/DifficultyCalculatorTest.cs new file mode 100644 index 0000000000..c6a7ff7cf4 --- /dev/null +++ b/osu.Game/Tests/Beatmaps/DifficultyCalculatorTest.cs @@ -0,0 +1,44 @@ +// 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.IO; +using System.Reflection; +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Formats; +using osu.Game.Rulesets.Difficulty; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Tests.Beatmaps +{ + [TestFixture] + public abstract class DifficultyCalculatorTest + { + private const string resource_namespace = "Testing.Beatmaps"; + + protected abstract string ResourceAssembly { get; } + + protected void Test(double expected, string name, params Mod[] mods) + => Assert.AreEqual(expected, CreateDifficultyCalculator(getBeatmap(name)).Calculate(mods).StarRating); + + private WorkingBeatmap getBeatmap(string name) + { + using (var resStream = openResource($"{resource_namespace}.{name}.osu")) + using (var stream = new StreamReader(resStream)) + { + var decoder = Decoder.GetDecoder(stream); + ((LegacyBeatmapDecoder)decoder).ApplyOffsets = false; + return new TestWorkingBeatmap(decoder.Decode(stream)); + } + } + + private Stream openResource(string name) + { + var localPath = Path.GetDirectoryName(Uri.UnescapeDataString(new UriBuilder(Assembly.GetExecutingAssembly().CodeBase).Path)); + return Assembly.LoadFrom(Path.Combine(localPath, $"{ResourceAssembly}.dll")).GetManifestResourceStream($@"{ResourceAssembly}.Resources.{name}"); + } + + protected abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap); + } +}