mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-29 22:58:18 -05:00
Get destination match in algorithms
This commit is contained in:
@@ -6,10 +6,12 @@ import {
|
||||
Match,
|
||||
TeamIdentifier,
|
||||
} from "./algorithms";
|
||||
import { countRounds } from "./bracket";
|
||||
|
||||
const AmountOfTeams = suite("Amount of teams");
|
||||
const Byes = suite("Byes");
|
||||
const Seeds = suite("Seeds");
|
||||
const BracketPaths = suite("Bracket path");
|
||||
const FillParticipantsWithNull = suite(
|
||||
"fillParticipantsWithNullTillPowerOfTwo()"
|
||||
);
|
||||
@@ -81,6 +83,52 @@ Seeds("First and second seed are spread apart", () => {
|
||||
);
|
||||
});
|
||||
|
||||
BracketPaths("Following winners", () => {
|
||||
const bracket16 = eliminationBracket(16, "DE");
|
||||
const count = countRounds(bracket16);
|
||||
|
||||
let latest: Match = bracket16.winners[0];
|
||||
let rounds = 0;
|
||||
let roundIds = new Set();
|
||||
while (latest) {
|
||||
rounds++;
|
||||
roundIds.add(latest.id);
|
||||
if (!latest.winnerDestinationMatch) {
|
||||
break;
|
||||
}
|
||||
assert.equal(latest.side, "winners");
|
||||
assert.ok(latest.loserDestinationMatch);
|
||||
latest = latest.winnerDestinationMatch;
|
||||
}
|
||||
|
||||
// no duplicate rounds
|
||||
assert.equal(roundIds.size, rounds);
|
||||
|
||||
assert.equal(rounds, count.winners);
|
||||
});
|
||||
|
||||
BracketPaths("Following losers", () => {
|
||||
const bracket16 = eliminationBracket(16, "DE");
|
||||
const count = countRounds(bracket16);
|
||||
|
||||
let latest: Match = bracket16.winners[0];
|
||||
let rounds = 0;
|
||||
let roundIds = new Set();
|
||||
while (latest) {
|
||||
rounds++;
|
||||
roundIds.add(latest.id);
|
||||
if (!latest.winnerDestinationMatch && !latest.loserDestinationMatch) {
|
||||
break;
|
||||
}
|
||||
latest = (latest.loserDestinationMatch ?? latest.winnerDestinationMatch)!;
|
||||
}
|
||||
|
||||
// no duplicate rounds
|
||||
assert.equal(roundIds.size, rounds);
|
||||
|
||||
assert.equal(rounds, count.losers + 3); // 3 rounds of winners: first round, grand finals & bracket reset
|
||||
});
|
||||
|
||||
FillParticipantsWithNull("17", () => {
|
||||
const participants: TeamIdentifier[] = new Array(17)
|
||||
.fill(null)
|
||||
@@ -120,4 +168,5 @@ function teamWithBye(matches: Match[]) {
|
||||
AmountOfTeams.run();
|
||||
Byes.run();
|
||||
Seeds.run();
|
||||
BracketPaths.run();
|
||||
FillParticipantsWithNull.run();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import invariant from "tiny-invariant";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import type { EliminationBracketSide } from "./bracket";
|
||||
|
||||
/** Singe/Double Elimination bracket algorithm that handles byes
|
||||
* @link https://stackoverflow.com/a/59615574 */
|
||||
@@ -57,6 +58,7 @@ export function eliminationBracket(
|
||||
const firstRoundMatch = createMatch({
|
||||
upperTeam,
|
||||
lowerTeam,
|
||||
side: "winners",
|
||||
});
|
||||
|
||||
matchesWQueue.push(firstRoundMatch);
|
||||
@@ -74,8 +76,12 @@ export function eliminationBracket(
|
||||
const winnersBracketMatch = createMatch({
|
||||
match1,
|
||||
match2,
|
||||
side: "winners",
|
||||
});
|
||||
|
||||
match1.winnerDestinationMatch = winnersBracketMatch;
|
||||
match2.winnerDestinationMatch = winnersBracketMatch;
|
||||
|
||||
matchesWQueue.push(winnersBracketMatch);
|
||||
bracket.winners.push(winnersBracketMatch);
|
||||
// add match to backfill for Lower Queue
|
||||
@@ -121,8 +127,20 @@ export function eliminationBracket(
|
||||
const losersMatch = createMatch({
|
||||
match1,
|
||||
match2,
|
||||
side: "losers",
|
||||
});
|
||||
|
||||
match1[
|
||||
match1.side === "winners"
|
||||
? "loserDestinationMatch"
|
||||
: "winnerDestinationMatch"
|
||||
] = losersMatch;
|
||||
match2[
|
||||
match2.side === "winners"
|
||||
? "loserDestinationMatch"
|
||||
: "winnerDestinationMatch"
|
||||
] = losersMatch;
|
||||
|
||||
matchesLQueue.push(losersMatch);
|
||||
bracket.losers.push(losersMatch);
|
||||
}
|
||||
@@ -137,13 +155,23 @@ export function eliminationBracket(
|
||||
const grandFinals = createMatch({
|
||||
match1,
|
||||
match2,
|
||||
side: "winners",
|
||||
});
|
||||
|
||||
match1.winnerDestinationMatch = grandFinals;
|
||||
match2.winnerDestinationMatch = grandFinals;
|
||||
|
||||
bracket.winners.push(grandFinals);
|
||||
|
||||
const bracketReset = createMatch({
|
||||
match1: grandFinals,
|
||||
match2: grandFinals,
|
||||
side: "winners",
|
||||
});
|
||||
|
||||
grandFinals.winnerDestinationMatch = bracketReset;
|
||||
grandFinals.loserDestinationMatch = bracketReset;
|
||||
|
||||
bracket.winners.push(bracketReset);
|
||||
|
||||
return bracket;
|
||||
@@ -212,6 +240,9 @@ export interface Match {
|
||||
match1?: Match;
|
||||
/** Match that leads to this match */
|
||||
match2?: Match;
|
||||
loserDestinationMatch?: Match;
|
||||
winnerDestinationMatch?: Match;
|
||||
side: EliminationBracketSide;
|
||||
}
|
||||
|
||||
export interface Bracket {
|
||||
|
||||
Reference in New Issue
Block a user