Skip to content

Commit

Permalink
Merge pull request #237 from Givikap120/fix_acc_formula_console
Browse files Browse the repository at this point in the history
Fix accuracy formula being wrong for stable scores in CLI
  • Loading branch information
smoogipoo authored Dec 6, 2024
2 parents a5be3a7 + 00ea84b commit a07a1a6
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 16 deletions.
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 class OsuSimulateCommand : SimulateCommand

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 @@ private static Dictionary<HitResult, int> generateHitResults(IBeatmap beatmap, d
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 @@ protected override double GetAccuracy(IBeatmap beatmap, Dictionary<HitResult, in
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

0 comments on commit a07a1a6

Please sign in to comment.