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

Fix accuracy formula being wrong for stable scores in CLI #237

Merged
merged 2 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion PerformanceCalculator/Simulate/CatchSimulateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using osu.Game.Rulesets;
using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -35,7 +36,7 @@ public class CatchSimulateCommand : SimulateCommand

public override Ruleset Ruleset => new CatchRuleset();

protected override Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap) => generateHitResults(beatmap, Accuracy / 100, Misses, Mehs, Goods);
protected override Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap, Mod[] mods) => generateHitResults(beatmap, Accuracy / 100, Misses, Mehs, Goods);

private static Dictionary<HitResult, int> generateHitResults(IBeatmap beatmap, double accuracy, int countMiss, int? countMeh, int? countGood)
{
Expand Down
3 changes: 2 additions & 1 deletion PerformanceCalculator/Simulate/ManiaSimulateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;

namespace PerformanceCalculator.Simulate
Expand All @@ -35,7 +36,7 @@ public class ManiaSimulateCommand : SimulateCommand

public override Ruleset Ruleset => new ManiaRuleset();

protected override Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap) => generateHitResults(beatmap, Accuracy / 100, Misses, Mehs, oks, Goods, greats);
protected override Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap, Mod[] mods) => generateHitResults(beatmap, Accuracy / 100, Misses, Mehs, oks, Goods, greats);

private static Dictionary<HitResult, int> generateHitResults(IBeatmap beatmap, double accuracy, int countMiss, int? countMeh, int? countOk, int? countGood, int? countGreat)
{
Expand Down
55 changes: 44 additions & 11 deletions PerformanceCalculator/Simulate/OsuSimulateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
using McMaster.Extensions.CommandLineUtils;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Scoring;

Expand Down Expand Up @@ -43,9 +45,20 @@

public override Ruleset Ruleset => new OsuRuleset();

protected override Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap) => generateHitResults(beatmap, Accuracy / 100, Misses, Mehs, Goods, largeTickMisses, sliderTailMisses);
protected override Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap, Mod[] mods)
{
// Use lazer info only if score has sliderhead accuracy
if (mods.OfType<OsuModClassic>().Any(m => m.NoSliderHeadAccuracy.Value))
{
return generateHitResults(beatmap, Accuracy / 100, Misses, Mehs, Goods, null, null);
}
else
{
return generateHitResults(beatmap, Accuracy / 100, Misses, Mehs, Goods, largeTickMisses, sliderTailMisses);
}
}

private static Dictionary<HitResult, int> generateHitResults(IBeatmap beatmap, double accuracy, int countMiss, int? countMeh, int? countGood, int countLargeTickMisses, int countSliderTailMisses)
private static Dictionary<HitResult, int> generateHitResults(IBeatmap beatmap, double accuracy, int countMiss, int? countMeh, int? countGood, int? countLargeTickMisses, int? countSliderTailMisses)
{
int countGreat;

Expand Down Expand Up @@ -121,15 +134,21 @@
countGreat = (int)(totalResultCount - countGood - countMeh - countMiss);
}

return new Dictionary<HitResult, int>
var result = new Dictionary<HitResult, int>
{
{ HitResult.Great, countGreat },
{ HitResult.Ok, countGood ?? 0 },
{ HitResult.Meh, countMeh ?? 0 },
{ HitResult.LargeTickMiss, countLargeTickMisses },
{ HitResult.SliderTailHit, beatmap.HitObjects.Count(x => x is Slider) - countSliderTailMisses },
{ HitResult.Miss, countMiss }
};

if (countLargeTickMisses != null)
result[HitResult.LargeTickMiss] = countLargeTickMisses.Value;

if (countSliderTailMisses != null)
result[HitResult.SliderTailHit] = beatmap.HitObjects.Count(x => x is Slider) - countSliderTailMisses.Value;

return result;
}

protected override double GetAccuracy(IBeatmap beatmap, Dictionary<HitResult, int> statistics)
Expand All @@ -139,14 +158,28 @@
var countMeh = statistics[HitResult.Meh];
var countMiss = statistics[HitResult.Miss];

var countSliders = beatmap.HitObjects.Count(x => x is Slider);
var countSliderTailHit = statistics[HitResult.SliderTailHit];
var countLargeTicks = beatmap.HitObjects.Sum(obj => obj.NestedHitObjects.Count(x => x is SliderTick or SliderRepeat));
var countLargeTickHit = countLargeTicks - statistics[HitResult.LargeTickMiss];
double total = 6 * countGreat + 2 * countGood + countMeh;
double max = 6 * (countGreat + countGood + countMeh + countMiss);

if (statistics.ContainsKey(HitResult.SliderTailHit))

Check notice on line 164 in PerformanceCalculator/Simulate/OsuSimulateCommand.cs

View workflow job for this annotation

GitHub Actions / Code Quality

Dictionary lookup can be simplified with 'TryGetValue' in PerformanceCalculator\Simulate\OsuSimulateCommand.cs on line 164
{
var countSliders = beatmap.HitObjects.Count(x => x is Slider);
var countSliderTailHit = statistics[HitResult.SliderTailHit];

total += 3 * countSliderTailHit;
max += 3 * countSliders;
}

if (statistics.ContainsKey(HitResult.LargeTickMiss))

Check notice on line 173 in PerformanceCalculator/Simulate/OsuSimulateCommand.cs

View workflow job for this annotation

GitHub Actions / Code Quality

Dictionary lookup can be simplified with 'TryGetValue' in PerformanceCalculator\Simulate\OsuSimulateCommand.cs on line 173
{
var countLargeTicks = beatmap.HitObjects.Sum(obj => obj.NestedHitObjects.Count(x => x is SliderTick or SliderRepeat));
var countLargeTickHit = countLargeTicks - statistics[HitResult.LargeTickMiss];

double total = 6 * (countGreat + countGood + countMeh + countMiss) + 3 * countSliders + 0.6 * countLargeTicks;
total += 0.6 * countLargeTickHit;
max += 0.6 * countLargeTicks;
}

return (6 * countGreat + 2 * countGood + countMeh + 3 * countSliderTailHit + 0.6 * countLargeTickHit) / total;
return total / max;
}
}
}
5 changes: 3 additions & 2 deletions PerformanceCalculator/Simulate/SimulateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using McMaster.Extensions.CommandLineUtils;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;

Expand Down Expand Up @@ -66,7 +67,7 @@ public override void Execute()
var beatmap = workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, mods);

var beatmapMaxCombo = beatmap.GetMaxCombo();
var statistics = GenerateHitResults(beatmap);
var statistics = GenerateHitResults(beatmap, mods);
var scoreInfo = new ScoreInfo(beatmap.BeatmapInfo, ruleset.RulesetInfo)
{
Accuracy = GetAccuracy(beatmap, statistics),
Expand All @@ -83,7 +84,7 @@ public override void Execute()
OutputPerformance(scoreInfo, performanceAttributes, difficultyAttributes);
}

protected abstract Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap);
protected abstract Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap, Mod[] mods);

protected virtual double GetAccuracy(IBeatmap beatmap, Dictionary<HitResult, int> statistics) => 0;
}
Expand Down
3 changes: 2 additions & 1 deletion PerformanceCalculator/Simulate/TaikoSimulateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using McMaster.Extensions.CommandLineUtils;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko;

Expand All @@ -29,7 +30,7 @@ public class TaikoSimulateCommand : SimulateCommand

public override Ruleset Ruleset => new TaikoRuleset();

protected override Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap) => generateHitResults(Accuracy / 100, beatmap, Misses, Goods);
protected override Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap, Mod[] mods) => generateHitResults(Accuracy / 100, beatmap, Misses, Goods);

private static Dictionary<HitResult, int> generateHitResults(double accuracy, IBeatmap beatmap, int countMiss, int? countGood)
{
Expand Down
Loading