Skip to content

Commit

Permalink
Merge pull request #230 from Givikap120/fix_acc_formula
Browse files Browse the repository at this point in the history
Fix accuracy formula being wrong for lazer scores in GUI
  • Loading branch information
smoogipoo authored Nov 18, 2024
2 parents 89b8f3b + ee6b7c2 commit 3057db5
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 15 deletions.
48 changes: 36 additions & 12 deletions PerformanceCalculatorGUI/RulesetHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public static int AdjustManiaScore(int score, IReadOnlyList<Mod> mods)
return (int)Math.Round(1000000 * scoreMultiplier);
}

public static Dictionary<HitResult, int> GenerateHitResultsForRuleset(RulesetInfo ruleset, double accuracy, IBeatmap beatmap, int countMiss, int? countMeh, int? countGood, int countLargeTickMisses, int countSliderTailMisses)
public static Dictionary<HitResult, int> GenerateHitResultsForRuleset(RulesetInfo ruleset, double accuracy, IBeatmap beatmap, int countMiss, int? countMeh, int? countGood, int? countLargeTickMisses, int? countSliderTailMisses)
{
return ruleset.OnlineID switch
{
Expand All @@ -116,7 +116,7 @@ public static Dictionary<HitResult, int> GenerateHitResultsForRuleset(RulesetInf
};
}

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

Expand Down Expand Up @@ -192,17 +192,21 @@ private static Dictionary<HitResult, int> generateOsuHitResults(double accuracy,
countGreat = (int)(totalResultCount - countGood - countMeh - countMiss);
}

int sliderTailHits = beatmap.HitObjects.Count(x => x is Slider) - countSliderTailMisses;

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, sliderTailHits },
{ 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;
}

private static Dictionary<HitResult, int> generateTaikoHitResults(double accuracy, IBeatmap beatmap, int countMiss, int? countGood)
Expand Down Expand Up @@ -293,27 +297,47 @@ private static Dictionary<HitResult, int> generateManiaHitResults(double accurac
};
}

public static double GetAccuracyForRuleset(RulesetInfo ruleset, Dictionary<HitResult, int> statistics)
public static double GetAccuracyForRuleset(RulesetInfo ruleset, IBeatmap beatmap, Dictionary<HitResult, int> statistics)
{
return ruleset.OnlineID switch
{
0 => getOsuAccuracy(statistics),
0 => getOsuAccuracy(beatmap, statistics),
1 => getTaikoAccuracy(statistics),
2 => getCatchAccuracy(statistics),
3 => getManiaAccuracy(statistics),
_ => 0.0
};
}

private static double getOsuAccuracy(Dictionary<HitResult, int> statistics)
private static double getOsuAccuracy(IBeatmap beatmap, Dictionary<HitResult, int> statistics)
{
var countGreat = statistics[HitResult.Great];
var countGood = statistics[HitResult.Ok];
var countMeh = statistics[HitResult.Meh];
var countMiss = statistics[HitResult.Miss];
var total = countGreat + countGood + countMeh + countMiss;

return (double)((6 * countGreat) + (2 * countGood) + countMeh) / (6 * total);
double total = 6 * countGreat + 2 * countGood + countMeh;
double max = 6 * (countGreat + countGood + countMeh + countMiss);

if (statistics.ContainsKey(HitResult.SliderTailHit))
{
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))
{
var countLargeTicks = beatmap.HitObjects.Sum(obj => obj.NestedHitObjects.Count(x => x is SliderTick or SliderRepeat));
var countLargeTickHit = countLargeTicks - statistics[HitResult.LargeTickMiss];

total += 0.6 * countLargeTickHit;
max += 0.6 * countLargeTicks;
}

return total / max;
}

private static double getTaikoAccuracy(Dictionary<HitResult, int> statistics)
Expand Down
14 changes: 11 additions & 3 deletions PerformanceCalculatorGUI/Screens/SimulateScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -702,10 +702,18 @@ private void calculatePerformance()
if (ruleset.Value.OnlineID != -1)
{
// official rulesets can generate more precise hits from accuracy
statistics = RulesetHelper.GenerateHitResultsForRuleset(ruleset.Value, accuracyTextBox.Value.Value / 100.0, beatmap, missesTextBox.Value.Value, countMeh, countGood,
largeTickMissesTextBox.Value.Value, sliderTailMissesTextBox.Value.Value);
if (appliedMods.Value.OfType<OsuModClassic>().Any(m => m.NoSliderHeadAccuracy.Value))
{
statistics = RulesetHelper.GenerateHitResultsForRuleset(ruleset.Value, accuracyTextBox.Value.Value / 100.0, beatmap, missesTextBox.Value.Value, countMeh, countGood,
null, null);
}
else
{
statistics = RulesetHelper.GenerateHitResultsForRuleset(ruleset.Value, accuracyTextBox.Value.Value / 100.0, beatmap, missesTextBox.Value.Value, countMeh, countGood,
largeTickMissesTextBox.Value.Value, sliderTailMissesTextBox.Value.Value);
}

accuracy = RulesetHelper.GetAccuracyForRuleset(ruleset.Value, statistics);
accuracy = RulesetHelper.GetAccuracyForRuleset(ruleset.Value, beatmap, statistics);
}

var ppAttributes = performanceCalculator?.Calculate(new ScoreInfo(beatmap.BeatmapInfo, ruleset.Value)
Expand Down

0 comments on commit 3057db5

Please sign in to comment.