Improve current-game race outlook forecast#266
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e528dd7e91
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const roundsPlayed = players[0].roundsPlayed; | ||
| if (roundsPlayed < 3) return null; | ||
|
|
||
| const orderedPlayers = [...players].sort((a, b) => a.id.localeCompare(b.id)); |
There was a problem hiding this comment.
Split simultaneous crossings instead of ID-ordering them
When two or more players cross the threshold on the same simulated round with the same score, the winner scan only replaces on a strictly greater score, so this new deterministic ID sort awards every tied simulation to the lexicographically first player. This is easy to hit with zero-variance current-game deltas or the new integer clamping (for example two players both at 30 with [15,15,15] end up 100%/0% despite identical outlook), so tied simulations should be split or resolved without player-ID bias.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
This PR upgrades the scoring “Win Probability” feature from a pace-only projection to a deterministic, single-pass Monte Carlo “Race Outlook” forecast that reports win odds, next-round close odds, end-round ranges, and explicit unresolved outcomes, and updates the UI + tests accordingly.
Changes:
- Added
calcRaceForecast(with clamped per-round deltas, stable rounding/allocation, and unresolved outcome tracking) while keepingcalcWinProbabilitiesas a wrapper. - Replaced the Win Probability card’s “Projected finish” section with a new “Race Outlook” panel driven by the richer forecast output.
- Added/updated unit tests for clamping, deterministic ordering, remainder allocation stability, unresolved outcomes, and the new UI.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/lib/scoring/probability.ts | Introduces race forecast model + helpers (clamping, percentile ranges, stable percent allocation) and keeps legacy API wrapper. |
| src/lib/tests/probability.test.ts | Adds coverage for new forecast helpers/behaviors and determinism. |
| src/components/scoring/graphs/WinProbabilityCard.tsx | Switches UI from legacy projection to “Race Outlook” based on calcRaceForecast. |
| src/components/tests/scoring/WinProbabilityCard.test.tsx | Adds component tests validating the new unavailable state and Race Outlook UI. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export function calcWinProbabilities( | ||
| players: { id: string; score: number; roundsPlayed: number }[], | ||
| winThreshold: number, | ||
| deltasByPlayer?: Record<string, number[]> | ||
| ): Record<string, number> | null { | ||
| const forecast = calcRaceForecast(players, winThreshold, deltasByPlayer); | ||
| if (!forecast) return null; | ||
| return Object.fromEntries( | ||
| Object.values(forecast.players).map((player) => [ | ||
| player.id, | ||
| player.winProbability, | ||
| ]) | ||
| ); | ||
| } |
|
Closed as superseded by merged integration PR #270. |
Summary
Claude review
Testing
npm run lintnpm testRESEND_API_KEY=re_dummy npx next buildNote:
npm run buildis not runnable in this local env because it starts withprisma migrate deployagainst the placeholder local database before Next compiles.Integration/testing PR: #270 contains the full stack for end-to-end testing.