brackt/app/services/simulations/race-points.ts

24 lines
1,009 B
TypeScript
Raw Permalink Normal View History

Fix auto racing sims ignoring championship standings The IndyCar simulator gave a near-clinched championship leader ~60% to win the title. It was reporting the futures odds and nothing else. `event_type` has no race value, so a season_standings calendar (F1, IndyCar) is stored as `schedule_event` rows — the admin default for that scoring pattern. The simulator skipped exactly those rows when counting races, so it saw zero remaining races, took the branch labelled "pre-season", and never looked at `participant_season_results`. Since `sourceOdds` is an admin input that is never auto-refreshed, the output was whatever the market said months ago. With a realistic late-season field (leader on 601 pts vs 480, 2 races left, stale futures at -300) the old path returns ~55%; counting the races returns 100.0%. - Add `countSeasonRaces` in a new leaf model. A race is every event except `final_standings`, and completion is inferred from the event date, since nobody marks rows labelled "Non-Scoring" complete. Its own module because `scoring-event.ts` reaches back into `simulator.ts` through `scoring-calculator`. - Split "season over" from "pre-season". Both had `remainingRaces === 0`, so a finished season reverted to an odds draw instead of reporting the final standings. - Warn when a season has championship points but no calendar, in the simulator and as a non-blocking readiness warning on the setup page. - Replace proportional vig removal with a power devig. Dividing every runner by the same book sum guts the favourite in a 27-driver market: a 75% implied favourite came out at 55%, a -20000 near-lock at 95%. Power devig gives 69.5% and 99.3%. Unpriced drivers now floor at the bottom of the market instead of being handed 1/N. - Move the race points tables to their own module so tests can read them without tripping the manifest/registry import cycle. The existing tests missed all of this because their event fixtures used `eventType: "race"`, which is not a value the enum has. Rebuilt on real enum values, plus a regression test for the reported case. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUcV7KenckF893zQ46EDXt
2026-08-17 00:36:20 +00:00
/**
* Championship points tables for auto racing series.
*
* Stable series rules, not refreshable season data, so they live in code (see
* the hardcoding rules in docs/agents/simulators.md). Kept out of `registry.ts`
* so tests and callers can read a table without pulling in every simulator
* importing the registry first also trips the manifest/registry import cycle.
*
* Each table must be contiguous from P1 and monotonically decreasing: the
* simulator's award loop stops at the first unscored position.
*/
/** F1 points: positions 110. */
export const F1_RACE_POINTS: Record<number, number> = {
1: 25, 2: 18, 3: 15, 4: 12, 5: 10, 6: 8, 7: 6, 8: 4, 9: 2, 10: 1,
};
/** IndyCar standard race points: positions 126. */
export const INDYCAR_RACE_POINTS: Record<number, number> = {
1: 50, 2: 40, 3: 35, 4: 32, 5: 30, 6: 28, 7: 26, 8: 24, 9: 22, 10: 20,
11: 19, 12: 18, 13: 17, 14: 16, 15: 15, 16: 14, 17: 13, 18: 12, 19: 11, 20: 10,
21: 9, 22: 8, 23: 7, 24: 6, 25: 5, 26: 5,
};