mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-26 21:27:48 -05:00
Fix Swiss not counting every meeting between tied teams for the head-to-head tiebreaker
This commit is contained in:
@@ -215,6 +215,87 @@ describe("swiss standings - cross group ties", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("swiss standings - rematches between tied teams", () => {
|
||||
// 4-team Swiss with 5 rounds, so rounds 4 and 5 are forced rematches. Teams 1
|
||||
// and 2 finish 4-1, having met twice and split 1-1 (team 1 won the round 1
|
||||
// meeting, team 2 the round 4 one), so head-to-head is even and opponent set
|
||||
// win % should decide: team 2's opponents won 12 of 25 sets (48%), team 1's
|
||||
// 10 of 25 (40%).
|
||||
const swissTournamentWithRematches = () => {
|
||||
const data = Engine.create({
|
||||
type: "swiss",
|
||||
seeding: [1, 2, 3, 4],
|
||||
settings: { groupCount: 1, roundCount: 5 },
|
||||
});
|
||||
|
||||
const roundResults: Array<Array<[winnerId: number, loserId: number]>> = [
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4],
|
||||
],
|
||||
[
|
||||
[1, 3],
|
||||
[2, 4],
|
||||
],
|
||||
[
|
||||
[1, 4],
|
||||
[2, 3],
|
||||
],
|
||||
[
|
||||
[2, 1],
|
||||
[3, 4],
|
||||
],
|
||||
[
|
||||
[1, 4],
|
||||
[2, 3],
|
||||
],
|
||||
];
|
||||
|
||||
data.match = roundResults.flatMap((results, roundIdx) =>
|
||||
results.map(
|
||||
([winnerId, loserId], matchIdx): MatchData => ({
|
||||
id: roundIdx * 2 + matchIdx,
|
||||
stageId: data.stage[0].id,
|
||||
groupId: data.group[0].id,
|
||||
roundId: data.round[roundIdx].id,
|
||||
number: matchIdx + 1,
|
||||
opponent1: { id: winnerId, score: 2 },
|
||||
opponent2: { id: loserId, score: 0 },
|
||||
winnerSide: "opponent1",
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
return testTournament({
|
||||
ctx: {
|
||||
settings: {
|
||||
bracketProgression: [
|
||||
{
|
||||
type: "swiss",
|
||||
name: "Swiss",
|
||||
requiresCheckIn: false,
|
||||
settings: { groupCount: 1, roundCount: 5 },
|
||||
sources: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
it("counts every meeting between tied teams for the head-to-head tiebreaker", () => {
|
||||
const standings = swissTournamentWithRematches().bracketByIdx(0)!.standings;
|
||||
|
||||
const team1 = standings.find((s) => s.team.id === 1)!;
|
||||
const team2 = standings.find((s) => s.team.id === 2)!;
|
||||
|
||||
expect(team2.placement).toBe(1);
|
||||
expect(team1.stats?.lossesAgainstTied).toBe(1);
|
||||
expect(team2.stats?.winsAgainstTied).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("round robin standings", () => {
|
||||
it("should sort teams primarily by set wins (per group) in paddling pool 255", () => {
|
||||
const tournamentPP255 = new Tournament(PADDLING_POOL_255());
|
||||
|
||||
@@ -330,7 +330,7 @@ export class SwissBracket extends Bracket {
|
||||
|
||||
// they are different teams and are tied, let's check who won
|
||||
|
||||
const finishedMatchBetweenTeams = matches.find((match) => {
|
||||
const finishedMatchesBetweenTeams = matches.filter((match) => {
|
||||
const isBetweenTeams =
|
||||
(match.opponent1?.id === team.id &&
|
||||
match.opponent2?.id === team2.id) ||
|
||||
@@ -342,19 +342,18 @@ export class SwissBracket extends Bracket {
|
||||
return isBetweenTeams && isFinished;
|
||||
});
|
||||
|
||||
// they did not play each other
|
||||
if (!finishedMatchBetweenTeams) continue;
|
||||
for (const finishedMatchBetweenTeams of finishedMatchesBetweenTeams) {
|
||||
const wonTheirMatch =
|
||||
(finishedMatchBetweenTeams.opponent1!.id === team.id &&
|
||||
finishedMatchBetweenTeams.winnerSide === "opponent1") ||
|
||||
(finishedMatchBetweenTeams.opponent2!.id === team.id &&
|
||||
finishedMatchBetweenTeams.winnerSide === "opponent2");
|
||||
|
||||
const wonTheirMatch =
|
||||
(finishedMatchBetweenTeams.opponent1!.id === team.id &&
|
||||
finishedMatchBetweenTeams.winnerSide === "opponent1") ||
|
||||
(finishedMatchBetweenTeams.opponent2!.id === team.id &&
|
||||
finishedMatchBetweenTeams.winnerSide === "opponent2");
|
||||
|
||||
if (wonTheirMatch) {
|
||||
team.winsAgainstTied++;
|
||||
} else {
|
||||
team.lossesAgainstTied++;
|
||||
if (wonTheirMatch) {
|
||||
team.winsAgainstTied++;
|
||||
} else {
|
||||
team.lossesAgainstTied++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user