From c0b13c7e1fa33da7681957dd62326632cba564e1 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 22 Aug 2022 19:39:12 +0900 Subject: [PATCH] Refactor ScoreProcessor ComputeScore() methods --- .../Rulesets/Scoring/ScoreProcessorTest.cs | 4 +- .../PerformanceBreakdownCalculator.cs | 2 +- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 60 +------------------ osu.Game/Scoring/ScoreManager.cs | 2 +- .../OnlinePlay/Playlists/PlaylistsPlayer.cs | 2 +- 5 files changed, 8 insertions(+), 62 deletions(-) diff --git a/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs b/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs index 44ebdad2e4fe..7a45d1e7cf18 100644 --- a/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs +++ b/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs @@ -307,7 +307,7 @@ public void TestGetScoreWithExternalStatistics(HitResult result, int expectedSco HitObjects = { new TestHitObject(result) } }); - Assert.That(scoreProcessor.ComputeFinalScore(ScoringMode.Standardised, new ScoreInfo + Assert.That(scoreProcessor.ComputeScore(ScoringMode.Standardised, new ScoreInfo { Ruleset = new TestRuleset().RulesetInfo, MaxCombo = result.AffectsCombo() ? 1 : 0, @@ -350,7 +350,7 @@ public void TestLegacyComboIncrease() } }; - double totalScore = new TestScoreProcessor().ComputeFinalScore(ScoringMode.Standardised, testScore); + double totalScore = new TestScoreProcessor().ComputeScore(ScoringMode.Standardised, testScore); Assert.That(totalScore, Is.EqualTo(750_000)); // 500K from accuracy (100%), and 250K from combo (50%). } #pragma warning restore CS0618 diff --git a/osu.Game/Rulesets/Difficulty/PerformanceBreakdownCalculator.cs b/osu.Game/Rulesets/Difficulty/PerformanceBreakdownCalculator.cs index 4465f1a328a5..3fb12041d1d9 100644 --- a/osu.Game/Rulesets/Difficulty/PerformanceBreakdownCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/PerformanceBreakdownCalculator.cs @@ -66,7 +66,7 @@ private Task getPerfectPerformance(ScoreInfo score, Cance // calculate total score ScoreProcessor scoreProcessor = ruleset.CreateScoreProcessor(); scoreProcessor.Mods.Value = perfectPlay.Mods; - perfectPlay.TotalScore = (long)scoreProcessor.ComputeFinalScore(ScoringMode.Standardised, perfectPlay); + perfectPlay.TotalScore = (long)scoreProcessor.ComputeScore(ScoringMode.Standardised, perfectPlay); // compute rank achieved // default to SS, then adjust the rank with mods diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 5b21caee8457..f13e3e6de6cf 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -121,7 +121,7 @@ public ScoringValues MaximumScoringValues /// /// The maximum of a basic (non-tick and non-bonus) hitobject. - /// Only populated via or . + /// Only populated via or . /// private HitResult? maxBasicResult; @@ -281,7 +281,7 @@ private void updateScore() /// The to compute the total score of. /// The total score in the given . [Pure] - public double ComputeFinalScore(ScoringMode mode, ScoreInfo scoreInfo) + public double ComputeScore(ScoringMode mode, ScoreInfo scoreInfo) { if (!ruleset.RulesetInfo.Equals(scoreInfo.Ruleset)) throw new ArgumentException($"Unexpected score ruleset. Expected \"{ruleset.RulesetInfo.ShortName}\" but was \"{scoreInfo.Ruleset.ShortName}\"."); @@ -291,60 +291,6 @@ public double ComputeFinalScore(ScoringMode mode, ScoreInfo scoreInfo) return ComputeScore(mode, current, maximum); } - /// - /// Computes the total score of a partially-completed . This should be used when it is unknown whether a score is complete. - /// - /// - /// Requires to have been called before use. - /// - /// The to represent the score as. - /// The to compute the total score of. - /// The total score in the given . - [Pure] - public double ComputePartialScore(ScoringMode mode, ScoreInfo scoreInfo) - { - if (!ruleset.RulesetInfo.Equals(scoreInfo.Ruleset)) - throw new ArgumentException($"Unexpected score ruleset. Expected \"{ruleset.RulesetInfo.ShortName}\" but was \"{scoreInfo.Ruleset.ShortName}\"."); - - if (!beatmapApplied) - throw new InvalidOperationException($"Cannot compute partial score without calling {nameof(ApplyBeatmap)}."); - - ExtractScoringValues(scoreInfo, out var current, out _); - - return ComputeScore(mode, current, MaximumScoringValues); - } - - /// - /// Computes the total score of a given with a given custom max achievable combo. - /// - /// - /// This is useful for processing legacy scores in which the maximum achievable combo can be more accurately determined via external means (e.g. database values or difficulty calculation). - ///

Does not require to have been called before use.

- ///
- /// The to represent the score as. - /// The to compute the total score of. - /// The maximum achievable combo for the provided beatmap. - /// The total score in the given . - [Pure] - public double ComputeFinalLegacyScore(ScoringMode mode, ScoreInfo scoreInfo, int maxAchievableCombo) - { - if (!ruleset.RulesetInfo.Equals(scoreInfo.Ruleset)) - throw new ArgumentException($"Unexpected score ruleset. Expected \"{ruleset.RulesetInfo.ShortName}\" but was \"{scoreInfo.Ruleset.ShortName}\"."); - - double accuracyRatio = scoreInfo.Accuracy; - double comboRatio = maxAchievableCombo > 0 ? (double)scoreInfo.MaxCombo / maxAchievableCombo : 1; - - ExtractScoringValues(scoreInfo, out var current, out var maximum); - - // For legacy osu!mania scores, a full-GREAT score has 100% accuracy. If combined with a full-combo, the score becomes indistinguishable from a full-PERFECT score. - // To get around this, the accuracy ratio is always recalculated based on the hit statistics rather than trusting the score. - // Note: This cannot be applied universally to all legacy scores, as some rulesets (e.g. catch) group multiple judgements together. - if (scoreInfo.IsLegacyScore && scoreInfo.Ruleset.OnlineID == 3 && maximum.BaseScore > 0) - accuracyRatio = current.BaseScore / maximum.BaseScore; - - return ComputeScore(mode, accuracyRatio, comboRatio, current.BonusScore, maximum.CountBasicHitObjects); - } - /// /// Computes the total score from scoring values. /// @@ -454,7 +400,7 @@ public virtual void PopulateScore(ScoreInfo score) score.MaximumStatistics[result] = maximumResultCounts.GetValueOrDefault(result); // Populate total score after everything else. - score.TotalScore = (long)Math.Round(ComputeFinalScore(ScoringMode.Standardised, score)); + score.TotalScore = (long)Math.Round(ComputeScore(ScoringMode.Standardised, score)); } /// diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index 7367a1ef77ef..ecd37c761c8d 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -148,7 +148,7 @@ public async Task GetTotalScoreAsync([NotNull] ScoreInfo score, ScoringMod var scoreProcessor = ruleset.CreateScoreProcessor(); scoreProcessor.Mods.Value = score.Mods; - return (long)Math.Round(scoreProcessor.ComputeFinalLegacyScore(mode, score, beatmapMaxCombo.Value)); + return (long)Math.Round(scoreProcessor.ComputeScore(mode, score)); } /// diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsPlayer.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsPlayer.cs index 282c1db5855a..1c4d02bb1134 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsPlayer.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsPlayer.cs @@ -67,7 +67,7 @@ protected override async Task PrepareScoreForResultsAsync(Score score) { await base.PrepareScoreForResultsAsync(score).ConfigureAwait(false); - Score.ScoreInfo.TotalScore = (int)Math.Round(ScoreProcessor.ComputeFinalScore(ScoringMode.Standardised, Score.ScoreInfo)); + Score.ScoreInfo.TotalScore = (int)Math.Round(ScoreProcessor.ComputeScore(ScoringMode.Standardised, Score.ScoreInfo)); } protected override void Dispose(bool isDisposing)