1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-13 19:54:15 +08:00

Ranked Play: Work around rating data not always including user (#37310)

Fixes
https://discord.com/channels/188630481301012481/188630652340404224/1493678774540304505

The rating distribution is updated once every 5 minutes, so there are
periods where it may not include the local user's rating. This is simply
a workaround where it's considered if it's bounded by it.

Am a little surprised this is as easy to handle as it appears to be,
even if not the cleanest presentation (it's an edge case).
This commit is contained in:
Dan Balasescu
2026-04-16 14:36:02 +09:00
committed by GitHub
Unverified
parent 8050ee36ce
commit e6a74fd1f3
2 changed files with 44 additions and 1 deletions
@@ -61,6 +61,37 @@ namespace osu.Game.Tests.Visual.Matchmaking
AddStep("set empty data", () => graph.SetData([], null));
}
[Test]
public void TestOutOfBoundsUserRating()
{
AddStep("set data with max user rating", () =>
{
List<(int x, int y)> values = new List<(int x, int y)>();
for (int i = 400; i <= 2800; i += 100)
values.Add((i, (int)Math.Round(generateCount(i, 1600, 400, 7200))));
graph.SetData(values.ToArray(), 4000);
});
AddStep("set data with min user rating", () =>
{
List<(int x, int y)> values = new List<(int x, int y)>();
for (int i = 400; i <= 2800; i += 100)
values.Add((i, (int)Math.Round(generateCount(i, 1600, 400, 7200))));
graph.SetData(values.ToArray(), 0);
});
AddStep("set data with only user rating", () =>
{
List<(int x, int y)> values = new List<(int x, int y)>();
for (int i = 400; i <= 2800; i += 100)
values.Add((i, (int)Math.Round(generateCount(i, 1600, 400, 7200))));
graph.SetData([], 1500);
});
}
private static double generateCount(double x, double mean, double stdDev, double amplitude)
{
return amplitude * Math.Exp(-Math.Pow(x - mean, 2) / (2 * Math.Pow(stdDev, 2))) + Random.Shared.Next(300);
@@ -236,9 +236,21 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
data.Zip(data.Skip(1), (a, b) => Math.Abs(b.x - a.x)).DefaultIfEmpty().Min()
);
if (userRating < xRange.min)
{
this.data = this.data.Prepend((userRating.Value, 1)).ToArray();
xRange.min = userRating.Value;
}
if (userRating > xRange.max)
{
this.data = this.data.Append((userRating.Value, 1)).ToArray();
xRange.max = userRating.Value;
}
yRange = (
0,
(int)roundToSignificant(data.Select(d => d.y).DefaultIfEmpty().Max())
(int)roundToSignificant(this.data.Select(d => d.y).DefaultIfEmpty().Max())
);
updateGraph();