Fix division SPR comparing against tournament-wide seeds

This commit is contained in:
Kalle
2026-10-16 17:38:36 +03:00
parent fb88b1415c
commit a05e708085
3 changed files with 32 additions and 5 deletions

View File

@@ -312,16 +312,29 @@ describe("sprByTeamId", () => {
expect(result.get(4)).toBe(0);
});
test("returns 0 for a team whose seed is outside the standings", () => {
test("returns 0 for a team without a seed", () => {
const result = sprByTeamId(
standings([
{ id: 1, seed: 1, placement: 1 },
{ id: 2, seed: 9, placement: 2 },
{ id: 2, seed: null, placement: 1 },
{ id: 1, seed: 1, placement: 2 },
]),
);
expect(result.get(2)).toBe(0);
});
test("compares a division's teams by their seed order within that division", () => {
// division B of an A/B divisions tournament, seeds 1 & 3 went to division A
const result = sprByTeamId(
standings([
{ id: 4, seed: 4, placement: 1 },
{ id: 2, seed: 2, placement: 2 },
]),
);
expect(result.get(4)).toBe(1);
expect(result.get(2)).toBe(-1);
});
});
describe("winners", () => {
@@ -976,7 +989,7 @@ function playOut(
}
function standings(
teams: Array<{ id: number; seed: number; placement: number }>,
teams: Array<{ id: number; seed: number | null; placement: number }>,
): Standing[] {
return teams.map(({ id, seed, placement }) => ({
team: tournamentCtxTeam(id, { seed }),

View File

@@ -66,6 +66,7 @@ export function reNumberPlacements<T extends { placement: number }>(
/**
* SPR (Seed Performance Rating) of every team in the standings, keyed by tournament team id.
* Seeds are ranked among the given standings only, so a division's standings are compared to its own seed order.
* See https://web.archive.org/web/20250513034545/https://www.pgstats.com/articles/introducing-spr-and-uf
*/
export function sprByTeamId(standings: Standing[]): Map<number, number> {
@@ -75,11 +76,19 @@ export function sprByTeamId(standings: Standing[]): Map<number, number> {
.map((placement, index) => [placement, index]),
);
const seedRankByTeamId = new Map(
R.sortBy(
standings.filter((standing) => typeof standing.team.seed === "number"),
(standing) => standing.team.seed ?? 0,
).map((standing, rank) => [standing.team.id, rank]),
);
const result = new Map<number, number>();
for (const standing of standings) {
const seedRank = seedRankByTeamId.get(standing.team.id);
const expectedPlacement =
standings[(standing.team.seed ?? 0) - 1]?.placement;
typeof seedRank === "number" ? standings[seedRank]?.placement : undefined;
const expectedIndex = expectedPlacement
? indexByPlacement.get(expectedPlacement)
: undefined;

View File

@@ -0,0 +1,5 @@
---
navItem: medal
type: bug
---
Fixed tournament results showing the wrong SPR for teams in A/B divisions