Files
gridpilot.gg/adapters/bootstrap/racing/RacingStandingFactory.ts
2025-12-28 12:04:12 +01:00

59 lines
2.2 KiB
TypeScript

import { League } from '@core/racing/domain/entities/League';
import { Race } from '@core/racing/domain/entities/Race';
import { Result as RaceResult } from '@core/racing/domain/entities/result/Result';
import { Standing } from '@core/racing/domain/entities/Standing';
import { getPointsSystems } from '../PointsSystems';
export class RacingStandingFactory {
create(leagues: League[], races: Race[], results: RaceResult[]): Standing[] {
const pointsSystems = getPointsSystems();
const racesByLeague = new Map<string, Set<string>>();
for (const race of races) {
if (!race.status.isCompleted()) continue;
const set = racesByLeague.get(race.leagueId) ?? new Set<string>();
set.add(race.id);
racesByLeague.set(race.leagueId, set);
}
const standings: Standing[] = [];
for (const league of leagues) {
const leagueId = league.id.toString();
const completedRaceIds = racesByLeague.get(leagueId) ?? new Set<string>();
if (completedRaceIds.size === 0) continue;
const pointsTable = this.resolvePointsSystem(league, pointsSystems);
const byDriver = new Map<string, Standing>();
for (const result of results) {
if (!completedRaceIds.has(result.raceId.toString())) continue;
const driverId = result.driverId.toString();
const previousStanding = byDriver.get(driverId) ?? Standing.create({ leagueId, driverId, position: 1 });
const nextStanding = previousStanding.addRaceResult(result.position.toNumber(), pointsTable);
byDriver.set(driverId, nextStanding);
}
const sorted = Array.from(byDriver.values()).sort((a, b) => {
if (b.points.toNumber() !== a.points.toNumber()) return b.points.toNumber() - a.points.toNumber();
if (b.wins !== a.wins) return b.wins - a.wins;
return b.racesCompleted - a.racesCompleted;
});
sorted.forEach((standing, index) => standings.push(standing.updatePosition(index + 1)));
}
return standings;
}
private resolvePointsSystem(
league: League,
pointsSystems: Record<string, Record<number, number>>,
): Record<number, number> {
const settings = league.settings;
return settings.customPoints ?? pointsSystems[settings.pointsSystem] ?? pointsSystems['f1-2024'] ?? {};
}
}