fix: ties on final match of bracket
This commit is contained in:
@@ -53,6 +53,14 @@ interface KnockoutRoundView {
|
|||||||
projected?: boolean;
|
projected?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface BracketMatchEntry {
|
||||||
|
id: number;
|
||||||
|
player1: string;
|
||||||
|
player2: string;
|
||||||
|
currentTurnColor: 1 | 2 | null;
|
||||||
|
result: LiveGame["result"];
|
||||||
|
}
|
||||||
|
|
||||||
export default function SpectatePage() {
|
export default function SpectatePage() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const {
|
const {
|
||||||
@@ -305,6 +313,10 @@ export default function SpectatePage() {
|
|||||||
if (tournamentType === "KnockoutBracket" && !knockoutRawData) {
|
if (tournamentType === "KnockoutBracket" && !knockoutRawData) {
|
||||||
setSelectedGame((prev) => (prev === msg.matchId ? null : prev));
|
setSelectedGame((prev) => (prev === msg.matchId ? null : prev));
|
||||||
}
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
send(cmd.gameList());
|
||||||
|
send(cmd.playerList());
|
||||||
|
}, 750);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "GAME_TERMINATED":
|
case "GAME_TERMINATED":
|
||||||
@@ -386,8 +398,14 @@ export default function SpectatePage() {
|
|||||||
[players],
|
[players],
|
||||||
);
|
);
|
||||||
const knockoutBracket = useMemo(
|
const knockoutBracket = useMemo(
|
||||||
() => buildKnockoutBracket(knockoutRounds, liveGames, tournamentWinner),
|
() =>
|
||||||
[knockoutRounds, liveGames, tournamentWinner],
|
buildKnockoutBracket(
|
||||||
|
knockoutRounds,
|
||||||
|
gameList,
|
||||||
|
liveGames,
|
||||||
|
tournamentWinner,
|
||||||
|
),
|
||||||
|
[gameList, knockoutRounds, liveGames, tournamentWinner],
|
||||||
);
|
);
|
||||||
const seedingMatches = useMemo(() => {
|
const seedingMatches = useMemo(() => {
|
||||||
const seen = new Set<number>();
|
const seen = new Set<number>();
|
||||||
@@ -813,14 +831,37 @@ function parseKnockoutRounds(raw: string) {
|
|||||||
|
|
||||||
function buildKnockoutBracket(
|
function buildKnockoutBracket(
|
||||||
rounds: string[][],
|
rounds: string[][],
|
||||||
|
gameList: GameEntry[],
|
||||||
liveGames: Map<number, LiveGame>,
|
liveGames: Map<number, LiveGame>,
|
||||||
tournamentWinner: string | null,
|
tournamentWinner: string | null,
|
||||||
) {
|
) {
|
||||||
if (rounds.length === 0) return [] as KnockoutRoundView[];
|
if (rounds.length === 0) return [] as KnockoutRoundView[];
|
||||||
|
|
||||||
const liveGameEntries = Array.from(liveGames.values()).sort(
|
const activeMatchIds = new Set(gameList.map((game) => game.id));
|
||||||
(a, b) => b.id - a.id,
|
const bracketMatchEntries: BracketMatchEntry[] = [
|
||||||
);
|
...[...gameList]
|
||||||
|
.sort((a, b) => b.id - a.id)
|
||||||
|
.map((game) => {
|
||||||
|
const live = liveGames.get(game.id);
|
||||||
|
return {
|
||||||
|
id: game.id,
|
||||||
|
player1: game.player1,
|
||||||
|
player2: game.player2,
|
||||||
|
currentTurnColor: live?.currentTurnColor ?? null,
|
||||||
|
result: null,
|
||||||
|
} satisfies BracketMatchEntry;
|
||||||
|
}),
|
||||||
|
...Array.from(liveGames.values())
|
||||||
|
.sort((a, b) => b.id - a.id)
|
||||||
|
.filter((game) => !activeMatchIds.has(game.id))
|
||||||
|
.map((game) => ({
|
||||||
|
id: game.id,
|
||||||
|
player1: game.player1,
|
||||||
|
player2: game.player2,
|
||||||
|
currentTurnColor: game.currentTurnColor,
|
||||||
|
result: game.result,
|
||||||
|
})),
|
||||||
|
];
|
||||||
const displayRounds: Array<{
|
const displayRounds: Array<{
|
||||||
label: string;
|
label: string;
|
||||||
players: Array<string | null>;
|
players: Array<string | null>;
|
||||||
@@ -837,7 +878,7 @@ function buildKnockoutBracket(
|
|||||||
if (index % 2 !== 0) return acc;
|
if (index % 2 !== 0) return acc;
|
||||||
const player1 = source[index] ?? null;
|
const player1 = source[index] ?? null;
|
||||||
const player2 = source[index + 1] ?? null;
|
const player2 = source[index + 1] ?? null;
|
||||||
const liveMatch = findLiveMatch(liveGameEntries, player1, player2);
|
const liveMatch = findBracketMatch(bracketMatchEntries, player1, player2);
|
||||||
acc.push(
|
acc.push(
|
||||||
resolveLiveWinner(liveMatch, tournamentWinner, player1, player2),
|
resolveLiveWinner(liveMatch, tournamentWinner, player1, player2),
|
||||||
);
|
);
|
||||||
@@ -860,7 +901,7 @@ function buildKnockoutBracket(
|
|||||||
([player1, player2], matchIndex) => {
|
([player1, player2], matchIndex) => {
|
||||||
const nextRound = displayRounds[roundIndex + 1];
|
const nextRound = displayRounds[roundIndex + 1];
|
||||||
const nextRoundPlayer = nextRound?.players[matchIndex] ?? null;
|
const nextRoundPlayer = nextRound?.players[matchIndex] ?? null;
|
||||||
const liveMatch = findLiveMatch(liveGameEntries, player1, player2);
|
const liveMatch = findBracketMatch(bracketMatchEntries, player1, player2);
|
||||||
const displayPlayer1 = liveMatch?.player1 ?? player1;
|
const displayPlayer1 = liveMatch?.player1 ?? player1;
|
||||||
const displayPlayer2 = liveMatch?.player2 ?? player2;
|
const displayPlayer2 = liveMatch?.player2 ?? player2;
|
||||||
const hasAdvancedPastRound =
|
const hasAdvancedPastRound =
|
||||||
@@ -906,22 +947,21 @@ function pairPlayers(players: Array<string | null>) {
|
|||||||
return pairs;
|
return pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
function findLiveMatch(
|
function findBracketMatch(
|
||||||
liveGames: LiveGame[],
|
matches: BracketMatchEntry[],
|
||||||
player1: string | null,
|
player1: string | null,
|
||||||
player2: string | null,
|
player2: string | null,
|
||||||
) {
|
) {
|
||||||
if (!player1 || !player2) return null;
|
if (!player1 || !player2) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
liveGames.find((game) =>
|
matches.find((game) => samePlayers(game.player1, game.player2, player1, player2)) ??
|
||||||
samePlayers(game.player1, game.player2, player1, player2),
|
null
|
||||||
) ?? null
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveLiveWinner(
|
function resolveLiveWinner(
|
||||||
liveMatch: LiveGame | null,
|
liveMatch: BracketMatchEntry | null,
|
||||||
tournamentWinner: string | null,
|
tournamentWinner: string | null,
|
||||||
player1: string | null,
|
player1: string | null,
|
||||||
player2: string | null,
|
player2: string | null,
|
||||||
|
|||||||
Reference in New Issue
Block a user