Fix wonky group letters after Z (many teams)

This commit is contained in:
Kalle 2025-02-23 11:09:11 +02:00
parent 0c470a99cb
commit dea2760d9f
7 changed files with 52 additions and 18 deletions

View File

@ -1,6 +1,6 @@
import type { Match as MatchType } from "~/modules/brackets-model";
import type { Bracket as BracketType } from "../../core/Bracket";
import { groupNumberToLetter } from "../../tournament-bracket-utils";
import { groupNumberToLetters } from "../../tournament-bracket-utils";
import { Match } from "./Match";
import { PlacementsTable } from "./PlacementsTable";
import { RoundHeader } from "./RoundHeader";
@ -107,7 +107,7 @@ function getGroups(bracket: BracketType) {
);
result.push({
groupName: `Group ${groupNumberToLetter(group.number)}`,
groupName: `Group ${groupNumberToLetters(group.number)}`,
matches,
groupId: group.id,
});

View File

@ -11,7 +11,7 @@ import {
import { useSearchParamState } from "~/hooks/useSearchParamState";
import type { Match as MatchType } from "~/modules/brackets-model";
import type { Bracket as BracketType } from "../../core/Bracket";
import { groupNumberToLetter } from "../../tournament-bracket-utils";
import { groupNumberToLetters } from "../../tournament-bracket-utils";
import { Match } from "./Match";
import { PlacementsTable } from "./PlacementsTable";
import { RoundHeader } from "./RoundHeader";
@ -259,7 +259,7 @@ function getGroups(bracket: BracketType) {
);
result.push({
groupName: `Group ${groupNumberToLetter(group.number)}`,
groupName: `Group ${groupNumberToLetters(group.number)}`,
matches,
groupId: group.id,
});

View File

@ -34,7 +34,7 @@ import * as PickBan from "../core/PickBan";
import type { TournamentDataTeam } from "../core/Tournament.server";
import type { TournamentMatchLoaderData } from "../routes/to.$id.matches.$mid";
import {
groupNumberToLetter,
groupNumberToLetters,
mapCountPlayedInSetWithCertainty,
matchIsLocked,
pickInfoText,
@ -102,9 +102,9 @@ export function StartedMatch({
.find((group) => group.id === match?.group_id);
return tournament.resolvePoolCode({
hostingTeamId,
groupLetter:
groupLetters:
group && bracket?.type === "round_robin"
? groupNumberToLetter(group.number)
? groupNumberToLetters(group.number)
: undefined,
bracketNumber:
hasRoundRobin && bracket?.type !== "round_robin"

View File

@ -25,7 +25,7 @@ import { assertUnreachable } from "~/utils/types";
import { userSubmittedImage } from "~/utils/urls";
import {
fillWithNullTillPowerOfTwo,
groupNumberToLetter,
groupNumberToLetters,
} from "../tournament-bracket-utils";
import { Bracket } from "./Bracket";
import * as Swiss from "./Swiss";
@ -684,11 +684,11 @@ export class Tournament {
resolvePoolCode({
hostingTeamId,
groupLetter,
groupLetters,
bracketNumber,
}: {
hostingTeamId: number;
groupLetter?: string;
groupLetters?: string;
bracketNumber?: number;
}) {
const tournamentNameWithoutOnlyLetters = this.ctx.name.replace(
@ -716,7 +716,7 @@ export class Tournament {
return {
prefix,
suffix:
globalSuffix ?? groupLetter ?? bracketNumber ?? hostingTeamId % 10,
globalSuffix ?? groupLetters ?? bracketNumber ?? hostingTeamId % 10,
};
}
@ -956,7 +956,7 @@ export class Tournament {
(round) => round.id === match.round_id,
);
roundName = `Groups ${group?.number ? groupNumberToLetter(group.number) : ""}${round?.number ?? ""}.${match.number}`;
roundName = `Groups ${group?.number ? groupNumberToLetters(group.number) : ""}${round?.number ?? ""}.${match.number}`;
} else if (bracket.type === "swiss") {
const group = bracket.data.group.find(
(group) => group.id === match.group_id,
@ -967,7 +967,7 @@ export class Tournament {
const oneGroupOnly = bracket.data.group.length === 1;
roundName = `Swiss${oneGroupOnly ? "" : " Group"} ${group?.number && !oneGroupOnly ? groupNumberToLetter(group.number) : ""} ${round?.number ?? ""}.${match.number}`;
roundName = `Swiss${oneGroupOnly ? "" : " Group"} ${group?.number && !oneGroupOnly ? groupNumberToLetters(group.number) : ""} ${round?.number ?? ""}.${match.number}`;
} else if (
bracket.type === "single_elimination" ||
bracket.type === "double_elimination"

View File

@ -59,7 +59,7 @@ import {
} from "../tournament-bracket-schemas.server";
import {
bracketSubscriptionKey,
groupNumberToLetter,
groupNumberToLetters,
isSetOverByScore,
matchIsLocked,
matchSubscriptionKey,
@ -745,7 +745,7 @@ function MatchHeader() {
(round) => round.id === match.round_id,
);
roundName = `Groups ${group?.number ? groupNumberToLetter(group.number) : ""}${round?.number ?? ""}.${match.number}`;
roundName = `Groups ${group?.number ? groupNumberToLetters(group.number) : ""}${round?.number ?? ""}.${match.number}`;
} else if (bracket.type === "swiss") {
const group = bracket.data.group.find(
(group) => group.id === match.group_id,
@ -756,7 +756,7 @@ function MatchHeader() {
const oneGroupOnly = bracket.data.group.length === 1;
roundName = `Swiss${oneGroupOnly ? "" : " Group"} ${group?.number && !oneGroupOnly ? groupNumberToLetter(group.number) : ""} ${round?.number ?? ""}.${match.number}`;
roundName = `Swiss${oneGroupOnly ? "" : " Group"} ${group?.number && !oneGroupOnly ? groupNumberToLetters(group.number) : ""} ${round?.number ?? ""}.${match.number}`;
} else if (
bracket.type === "single_elimination" ||
bracket.type === "double_elimination"

View File

@ -1,6 +1,7 @@
import { describe, expect, test } from "vitest";
import {
fillWithNullTillPowerOfTwo,
groupNumberToLetters,
mapCountPlayedInSetWithCertainty,
} from "./tournament-bracket-utils";
@ -53,3 +54,21 @@ describe("fillWithNullTillPowerOfTwo()", () => {
});
}
});
const groupNumberToLettersParamsToResult = [
{ groupNumber: 1, expected: "A" },
{ groupNumber: 26, expected: "Z" },
{ groupNumber: 27, expected: "AA" },
{ groupNumber: 52, expected: "AZ" },
{ groupNumber: 53, expected: "BA" },
{ groupNumber: 702, expected: "ZZ" },
{ groupNumber: 703, expected: "AAA" },
];
describe("groupNumberToLetters()", () => {
for (const { groupNumber, expected } of groupNumberToLettersParamsToResult) {
test(`groupNumber=${groupNumber} -> ${expected}`, () => {
expect(groupNumberToLetters(groupNumber)).toBe(expected);
});
}
});

View File

@ -206,8 +206,23 @@ export function pickInfoText({
return "";
}
export function groupNumberToLetter(groupNumber: number) {
return String.fromCharCode(65 + groupNumber - 1).toUpperCase();
/**
* Converts a group number to its corresponding letter representation.
*
* The function takes a one-based group number and converts it to a string
* of uppercase letters, similar to how Excel columns are labeled (e.g., 1 -> 'A', 26 -> 'Z', 27 -> 'AA').
*
* @param groupNumber - The one-based group number to convert.
* @returns The letter representation of the group number.
*/
export function groupNumberToLetters(groupNumber: number) {
let letters = "";
let num = groupNumber - 1; // Adjust for one-based input
while (num >= 0) {
letters = String.fromCharCode((num % 26) + 65) + letters;
num = Math.floor(num / 26) - 1;
}
return letters;
}
export function isSetOverByResults({