diff --git a/app/features/tournament-bracket/tournament-bracket-utils.ts b/app/features/tournament-bracket/tournament-bracket-utils.ts index f7e964285..08d25902b 100644 --- a/app/features/tournament-bracket/tournament-bracket-utils.ts +++ b/app/features/tournament-bracket/tournament-bracket-utils.ts @@ -84,7 +84,10 @@ export function resolveTournamentStageSettings( case "SE": return {}; case "DE": - return { grandFinal: "double" }; + return { + grandFinal: "double", + seedOrdering: ["space_between"], + }; default: { assertUnreachable(format); } diff --git a/app/modules/brackets-manager/ordering.ts b/app/modules/brackets-manager/ordering.ts index fb430b005..f3e7bf9b9 100644 --- a/app/modules/brackets-manager/ordering.ts +++ b/app/modules/brackets-manager/ordering.ts @@ -2,6 +2,7 @@ import type { SeedOrdering } from "brackets-model"; import type { OrderingMap } from "./types"; +import invariant from "tiny-invariant"; export const ordering: OrderingMap = { natural: (array: T[]) => [...array], @@ -20,6 +21,34 @@ export const ordering: OrderingMap = { result.push(array[i + 1], array[i]); return result; }, + // https://stackoverflow.com/a/11631472 + space_between: (array: T[]) => { + const numPlayers = array.length; + + const rounds = Math.log(numPlayers) / Math.log(2) - 1; + let pls = [1, 2]; + for (let i = 0; i < rounds; i++) { + pls = nextLayer(pls); + } + return seedsToOrderedArray(pls); + function nextLayer(pls: number[]) { + const out: number[] = []; + const length = pls.length * 2 + 1; + pls.forEach(function (d) { + out.push(d); + out.push(length - d); + }); + return out; + } + // this part added to the SO answer + function seedsToOrderedArray(seeds: number[]) { + return seeds.map((seed) => { + const participant = array[seed - 1]; + invariant(participant !== undefined, `No participant for seed ${seed}`); + return participant; + }); + } + }, inner_outer: (array: T[]) => { if (array.length === 2) return array;