Get destination match in algorithms

This commit is contained in:
Kalle (Sendou)
2021-12-21 10:28:50 +02:00
parent 31b0b34c80
commit cc142cca0f
2 changed files with 80 additions and 0 deletions

View File

@@ -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();

View File

@@ -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 {