Skip to content

Commit

Permalink
Merge pull request #410 from Piotrekol/maniaPpCalc
Browse files Browse the repository at this point in the history
Fix: Mania pp values
  • Loading branch information
Piotrekol authored Nov 13, 2024
2 parents f2448a4 + d031400 commit 0565688
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 21 deletions.
17 changes: 8 additions & 9 deletions PpCalculator/ManiaCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,18 @@ public class ManiaCalculator : PpCalculator

protected override Dictionary<HitResult, int> GenerateHitResults(double accuracy, IReadOnlyList<HitObject> hitObjects, int countMiss, int? countMeh, int? countGood, int? countKatu = null, int? hit300 = null)
{
// One judgement per normal note. Two judgements per hold note (head + tail).
var totalHits = hitObjects.Count + hitObjects.Count(ho => ho is HoldNote);

var totalHits = hitObjects.Count;

if (countMeh != null || countKatu != null || countGood != null || hit300 != null)
{
int countPerfect = totalHits - (countMiss + (countMeh ?? 0) + (countKatu ?? 0) + (countGood ?? 0) + (hit300 ?? 0));
int countPerfect = Gekis ?? totalHits - (countMiss + (countMeh ?? 0) + (countKatu ?? 0) + (countGood ?? 0) + (hit300 ?? 0));

return new Dictionary<HitResult, int>
{
[HitResult.Perfect] = countPerfect,
[HitResult.Great] = hit300 ?? 0,
[HitResult.Good] = countGood ?? 0,
[HitResult.Ok] = countKatu ?? 0,
[HitResult.Good] = countKatu ?? 0,
[HitResult.Ok] = countGood ?? 0,
[HitResult.Meh] = countMeh ?? 0,
[HitResult.Miss] = countMiss
};
Expand All @@ -44,10 +43,10 @@ protected override Dictionary<HitResult, int> GenerateHitResults(double accuracy
int delta = targetTotal - remainingHits;

// Each great and perfect increases total by 5 (great-meh=5)
// There is no difference in accuracy between them, so just halve arbitrarily (favouring perfects for an odd number).
// While there is no difference in accuracy between them, they do differ in context of performance points calculation. Assume all perfect.
int greatsAndPerfects = Math.Min(delta / 5, remainingHits);
int countGreat = greatsAndPerfects / 2;
int perfects = greatsAndPerfects - countGreat;
int countGreat = 0;
int perfects = greatsAndPerfects;
delta -= (countGreat + perfects) * 5;
remainingHits -= countGreat + perfects;

Expand Down
1 change: 1 addition & 0 deletions PpCalculator/PpCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public virtual string[] Mods
public virtual int? Goods { get; set; }
public int? Katus { get; set; }
public int? Hit300 { get; set; }
public int? Gekis { get; set; }

protected virtual ScoreInfo ScoreInfo { get; }
protected PerformanceCalculator PerformanceCalculator { get; set; }
Expand Down
18 changes: 10 additions & 8 deletions PpCalculatorTests/PpCalculatorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ public void CalculateCtbTest(int c100, int cKatu, int c50, int cMiss, int combo,
=> CalculateTest(c100, c50, cMiss, combo, mods, expectedPp, mapId, new CtbCalculator(), cKatu: cKatu);

[Test]
//mania score consists of: Geki(c300P, auto calculated),c300,Katu(c200),c100,c50,cMiss
[TestCase(673, 20, 0, 0, 0, 3835, "", 862.3565, 3563179, 990307)]
[TestCase(1486, 131, 13, 11, 28, 1256, "", 745.3009, 3449261, 913494)]
public void CalculateManiaTest(int c300, int cKatu, int c100, int c50, int cMiss, int combo, string mods, double expectedPp, int mapId, int score)
=> CalculateTest(c100, c50, cMiss, combo, mods, expectedPp, mapId, new ManiaCalculator(), score, c300, cKatu);

public void CalculateTest(int c100, int? c50, int cMiss, int combo, string mods, double expectedPp, int mapId, BasePpCalculator ppCalculator, int score = 0, int c300 = 0, int cKatu = 0)
//mania score consists of: Geki(c300P),c300,Katu(c200),c100,c50,cMiss
[TestCase(null, 1152, 133, 10, 10, 15, 788, "", 709.0555, 3563179)]
[TestCase(2713, 504, 16, 3, 0, 0, 3797, "", 870.3794, 3563179)] // https://osu.ppy.sh/scores/mania/569388665
[TestCase(null, 504, 16, 3, 0, 0, 3797, "", 870.3794, 3563179)] // same score as above - tests geki inference
[TestCase(null, 1439, 30, 1, 0, 2, 4776, "", 787.2022, 3449261)] // https://osu.ppy.sh/scores/mania/565258177
public void CalculateManiaTest(int? geki, int c300, int cKatu, int c100, int c50, int cMiss, int combo, string mods, double expectedPp, int mapId)
=> CalculateTest(c100, c50, cMiss, combo, mods, expectedPp, mapId, new ManiaCalculator(), c300, cKatu, geki);

public void CalculateTest(int c100, int? c50, int cMiss, int combo, string mods, double expectedPp, int mapId, BasePpCalculator ppCalculator, int c300 = 0, int cKatu = 0, int? cGeki = 0)
{
ppCalculator.PreProcess(GetMapPath(mapId));
ppCalculator.Hit300 = c300;
Expand All @@ -51,7 +53,7 @@ public void CalculateTest(int c100, int? c50, int cMiss, int combo, string mods,
ppCalculator.Mehs = c50;
ppCalculator.Misses = cMiss;
ppCalculator.Combo = combo;
ppCalculator.Score = score;
ppCalculator.Gekis = cGeki;
ppCalculator.Mods = mods.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);

double calculatedPp = ppCalculator.Calculate(CancellationToken.None).Total;
Expand Down
1 change: 1 addition & 0 deletions PpCalculatorTypes/IPpCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public interface IPpCalculator
int? Goods { get; set; }
int? Katus { get; set; }
int? Hit300 { get; set; }
int? Gekis { get; set; }
int RulesetId { get; }
double BeatmapLength { get; }
bool UseScoreMultiplier { get; set; }
Expand Down
7 changes: 3 additions & 4 deletions plugins/BeatmapPpReplacements/PpReplacements.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ public PpReplacements(ISettings settings)
},
{TokenMode.Mania,new Dictionary<string,PpValue>
{
{"mania_1_000_000PP",(c,ppCalculator,mods)=>GetPp(c,ppCalculator, 0, "", 1_000_000)},
{"mania_m1_000_000PP",(c,ppCalculator,mods)=>GetPp(c,ppCalculator, 0, mods, 1_000_000)},
{"mania_1_000_000PP",(c,ppCalculator,mods)=>GetPp(c,ppCalculator, 100, "")},
{"mania_m1_000_000PP",(c,ppCalculator,mods)=>GetPp(c,ppCalculator, 100, mods)},
}
}
};
Expand Down Expand Up @@ -134,11 +134,10 @@ public async Task CreateTokensAsync(IMapSearchResult map, CancellationToken canc
ResetTokens(tokenMode == TokenMode.Osu ? TokenMode.Mania : TokenMode.Osu);
}

private double GetPp(CancellationToken cancellationToken, IPpCalculator ppCalculator, double acc, string mods = "", int score = 0)
private double GetPp(CancellationToken cancellationToken, IPpCalculator ppCalculator, double acc, string mods = "")
{
ppCalculator.Mods = mods.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
ppCalculator.Accuracy = acc;
ppCalculator.Score = (int)(score * ppCalculator.ScoreMultiplier);
return Math.Round(ppCalculator.Calculate(cancellationToken).Total, 3);
}
}
Expand Down
1 change: 1 addition & 0 deletions plugins/OsuMemoryEventSource/LivePerformanceCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ private void PreparePpCalculator(IPpCalculator ppCalculator, RulesetPlayData pla
ppCalculator.Misses = play.HitMiss;
ppCalculator.Katus = Play.HitKatu;
ppCalculator.Hit300 = Play.Hit300;
ppCalculator.Gekis = Play.HitGeki;
ppCalculator.Combo = play.MaxCombo;
ppCalculator.Score = play.Score;
}
Expand Down

0 comments on commit 0565688

Please sign in to comment.