Skip to content

Commit

Permalink
chore: 試合番号を正しく生成できるように
Browse files Browse the repository at this point in the history
  • Loading branch information
laminne committed Jan 10, 2025
1 parent ed4bafe commit a7ab7ff
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 12 deletions.
12 changes: 11 additions & 1 deletion packages/kcms/src/match/service/generateMain.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ describe('GenerateMainMatchService', () => {
});

it('制約が存在しない場合はエラーになる', async () => {
const res = await service.handle('open', ['1'] as TeamID[]);
const res = await new GenerateMainMatchService(mainMatchRepository, idGenerator, {}).handle(
'elementary',
['1'] as TeamID[]
);
expect(Result.isErr(res)).toStrictEqual(true);
});

Expand All @@ -39,6 +42,8 @@ describe('GenerateMainMatchService', () => {
expect(Result.isErr(res)).toStrictEqual(false);
const actual = Result.unwrap(res);
expect(actual.length).toStrictEqual(2 - 1);
const matchNumbers = actual.map((m) => `${m.getCourseIndex()}-${m.getMatchIndex()}`);
expect(matchNumbers).toStrictEqual(['1-1']);
});

it('n=4のとき、試合が生成できる', async () => {
Expand All @@ -49,6 +54,9 @@ describe('GenerateMainMatchService', () => {
expect(Result.isErr(res)).toStrictEqual(false);
const actual = Result.unwrap(res);
expect(actual.length).toStrictEqual(4 - 1);

const matchNumbers = actual.map((m) => `${m.getCourseIndex()}-${m.getMatchIndex()}`);
expect(matchNumbers).toStrictEqual(['1-1', '2-1', '1-2']);
});

it('n=8のとき、試合が生成できる', async () => {
Expand All @@ -59,6 +67,8 @@ describe('GenerateMainMatchService', () => {
expect(Result.isErr(res)).toStrictEqual(false);
const actual = Result.unwrap(res);
expect(actual.length).toStrictEqual(8 - 1);
const matchNumbers = actual.map((m) => `${m.getCourseIndex()}-${m.getMatchIndex()}`);
expect(matchNumbers).toStrictEqual(['1-1', '2-1', '3-1', '1-2', '1-3', '2-2', '1-4']);
});

it('親が存在しない試合は1つだけ生成される', async () => {
Expand Down
43 changes: 32 additions & 11 deletions packages/kcms/src/match/service/generateMain.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Result } from '@mikuroxina/mini-fn';
import { DepartmentType } from 'config';
import { config, DepartmentType } from 'config';
import { SnowflakeIDGenerator } from '../../id/main';
import { TeamID } from '../../team/models/team';
import { ChildMatches, MainMatch, MainMatchID } from '../model/main';
Expand Down Expand Up @@ -32,7 +32,7 @@ export class GenerateMainMatchService {
}
const pair = Result.unwrap(pairRes);

const matchesRes = this.generateTournament(pair);
const matchesRes = this.generateTournament(departmentType, pair);
if (Result.isErr(matchesRes)) {
return matchesRes;
}
Expand Down Expand Up @@ -82,7 +82,6 @@ export class GenerateMainMatchService {
/*
* 3. 順位で並べてグルーピングする
* グループ数: n/4
* ToDo: n=4のときは2、n=2のときは1として扱うようにする
*/
const groupNum = ((n: number) => {
if (n === 4) return 2;
Expand All @@ -106,12 +105,13 @@ export class GenerateMainMatchService {
* トーナメントを生成する
*/
private generateTournament(
departmentType: DepartmentType,
firstRoundMatches: [TeamID | undefined, TeamID | undefined][]
): Result.Result<Error, MainMatch[]> {
// K: トーナメントのラウンド数(0が決勝) / V: そのラウンドの試合
const matches: Map<number, MainMatch[]> = new Map();
// 現在のラウンド数(0だとlog_2が0になるため1からスタート)
let round = 1;
let round = Math.floor(Math.log2(firstRoundMatches.length));
/*
試合を生成
Expand All @@ -122,21 +122,39 @@ export class GenerateMainMatchService {
NOTE: 注意 **ラウンドはトーナメント実行順とは逆方向に数えています(例(n=8):初戦: 2, 準決勝: 1, 決勝: 0)**
*/
for (let i = 1; i < firstRoundMatches.length * 2; i++) {
// K: コース番号 / V: そのコースの試合番号
const matchIndex: Map<number, number> = new Map(
config.match.main.course[departmentType].map((v) => [v, 1])
);
let courseIndex = 0;
for (let i = firstRoundMatches.length * 2 - 1; i !== 0; i--) {
if (Math.floor(Math.log2(i)) != round) {
round = Math.floor(Math.log2(i));
courseIndex = 0;
}
if (!matches.has(round)) {
matches.set(round, []);
}

if (courseIndex === config.match.main.course[departmentType].length) {
courseIndex = 0;
}

// 試合番号を生成する
const newMatchIndex = matchIndex.get(config.match.main.course[departmentType][courseIndex])!;
const newCourseIndex = config.match.main.course[departmentType][courseIndex];

matchIndex.set(config.match.main.course[departmentType][courseIndex], newMatchIndex + 1);
courseIndex++;

// 試合を生成する
// ToDo: 試合番号、部門を正しく埋める
const res = this.generateMainMatch(
'elementary',
departmentType,
[undefined, undefined],
undefined,
undefined
undefined,
newMatchIndex,
newCourseIndex
);
if (Result.isErr(res)) {
return res;
Expand Down Expand Up @@ -204,6 +222,7 @@ export class GenerateMainMatchService {
pair[1].setParentID(parent);
}
}

return Result.ok([...matches.entries()].map((v) => v[1]).flat());
}

Expand All @@ -212,7 +231,9 @@ export class GenerateMainMatchService {
departmentType: DepartmentType,
pair: [TeamID | undefined, TeamID | undefined],
parent: MainMatchID | undefined,
child: ChildMatches | undefined
child: ChildMatches | undefined,
matchIndex: number,
courseIndex: number
): Result.Result<Error, MainMatch> {
const id = this.idGenerator.generate<MainMatch>();
if (Result.isErr(id)) {
Expand All @@ -222,8 +243,8 @@ export class GenerateMainMatchService {
return Result.ok(
MainMatch.new({
id: Result.unwrap(id),
courseIndex: 1,
matchIndex: 1,
courseIndex,
matchIndex,
departmentType: departmentType,
teamID1: pair[0],
teamID2: pair[1],
Expand Down

0 comments on commit a7ab7ff

Please sign in to comment.