59 lines
2.2 KiB
TypeScript
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'] ?? {};
|
|
}
|
|
} |