fix: tiebreak ongeki scores based on p-score (#1282)

* fix: tiebreak ongeki scores based on p-score

* fix: add another test
This commit is contained in:
nairobi
2025-04-24 08:31:41 +01:00
committed by GitHub
parent 454dabd79e
commit bae16fbdc2
2 changed files with 147 additions and 13 deletions
@@ -1,13 +1,13 @@
import { ONGEKI_IMPL } from "./ongeki";
import db from "external/mongo/db";
import CreateLogCtx from "lib/logger/logger";
import { CreatePBDoc } from "lib/score-import/framework/pb/create-pb-doc";
import { CreatePBDoc, UpdateChartRanking } from "lib/score-import/framework/pb/create-pb-doc";
import { ONGEKI_BELL_LAMPS, ONGEKI_GRADES, ONGEKI_NOTE_LAMPS } from "tachi-common";
import t from "tap";
import { dmf, mkMockPB, mkMockScore } from "test-utils/misc";
import ResetDBState from "test-utils/resets";
import { TestingOngekiChart, TestingOngekiScorePB } from "test-utils/test-data";
import type { ProvidedMetrics, ScoreData } from "tachi-common";
import type { PBScoreDocument, ProvidedMetrics, ScoreData } from "tachi-common";
const baseMetrics: ProvidedMetrics["ongeki:Single"] = {
noteLamp: "CLEAR",
@@ -214,5 +214,122 @@ t.test("ONGEKI Implementation", (t) => {
t.end();
});
t.test("Ranking", (t) => {
t.beforeEach(ResetDBState);
t.test("Should tiebreak according to platinum score", async (t) => {
await db["personal-bests"].insert({
...TestingOngekiScorePB,
scoreData: {
...TestingOngekiScorePB.scoreData,
optional: {
...TestingOngekiScorePB.scoreData.optional,
platScore: 1000,
},
},
timeAchieved: 3,
userID: 1,
});
await db["personal-bests"].insert({
...TestingOngekiScorePB,
scoreData: {
...TestingOngekiScorePB.scoreData,
optional: {
...TestingOngekiScorePB.scoreData.optional,
platScore: 1001,
},
},
timeAchieved: 2,
userID: 2,
});
await db["personal-bests"].insert({
...TestingOngekiScorePB,
scoreData: {
...TestingOngekiScorePB.scoreData,
optional: {
...TestingOngekiScorePB.scoreData.optional,
platScore: 999,
},
},
timeAchieved: 1,
userID: 3,
});
await UpdateChartRanking("ongeki", "Single", TestingOngekiChart.chartID);
const pbs = (await db["personal-bests"].find({
chartID: TestingOngekiChart.chartID,
})) as Array<PBScoreDocument<"ongeki:Single">>;
t.strictSame(pbs.length, 3);
for (const pb of pbs) {
t.strictSame(pb.rankingData.outOf, 3);
if (pb.scoreData.optional.platScore === 999) {
t.strictSame(pb.rankingData.rank, 3);
} else if (pb.scoreData.optional.platScore === 1000) {
t.strictSame(pb.rankingData.rank, 2);
} else {
t.strictSame(pb.rankingData.rank, 1);
}
}
t.end();
});
t.test("Should not tiebreak if tech scores differ", async (t) => {
await db["personal-bests"].insert({
...TestingOngekiScorePB,
scoreData: {
...TestingOngekiScorePB.scoreData,
score: 1010000,
optional: {
...TestingOngekiScorePB.scoreData.optional,
platScore: 0,
},
},
userID: 1,
});
await db["personal-bests"].insert({
...TestingOngekiScorePB,
scoreData: {
...TestingOngekiScorePB.scoreData,
score: 1009999,
optional: {
...TestingOngekiScorePB.scoreData.optional,
platScore: 1001,
},
},
userID: 2,
});
await UpdateChartRanking("ongeki", "Single", TestingOngekiChart.chartID);
const [pb1, pb2] = (await db["personal-bests"].find(
{
chartID: TestingOngekiChart.chartID,
},
{
sort: {
[`rankingData.rank`]: 1,
},
}
)) as Array<PBScoreDocument<"ongeki:Single">>;
t.strictSame(pb1?.rankingData.outOf, 2);
t.strictSame(pb1?.rankingData.rank, 1);
t.strictSame(pb2?.rankingData.rank, 2);
t.strictSame(pb1?.scoreData.optional.platScore, 0);
t.strictSame(pb2?.scoreData.optional.platScore, 1001);
t.end();
});
t.end();
});
t.end();
});
@@ -129,17 +129,7 @@ export async function CreatePBDoc(
* Updates rankings on a given chart.
*/
export async function UpdateChartRanking(game: Game, playtype: Playtype, chartID: string) {
const gptConfig = GetGamePTConfig(game, playtype);
const scores = await db["personal-bests"].find(
{ chartID },
{
sort: {
[`scoreData.${gptConfig.defaultMetric}`]: -1,
timeAchieved: 1,
},
}
);
const scores = await GetSortedPBs(game, playtype, chartID);
const allRivals = await GetEveryonesRivalIDs(game, playtype);
@@ -186,3 +176,30 @@ export async function UpdateChartRanking(game: Game, playtype: Playtype, chartID
await db["personal-bests"].bulkWrite(bwrite, { ordered: false });
}
async function GetSortedPBs(game: Game, playtype: Playtype, chartID: string) {
const gptConfig = GetGamePTConfig(game, playtype);
if (game === "ongeki") {
return db["personal-bests"].find(
{ chartID },
{
sort: {
[`scoreData.score`]: -1,
[`scoreData.optional.platScore`]: -1,
timeAchieved: 1,
},
}
);
}
return db["personal-bests"].find(
{ chartID },
{
sort: {
[`scoreData.${gptConfig.defaultMetric}`]: -1,
timeAchieved: 1,
},
}
);
}