Reflect group stage in World Cup sim; seed R32 from real 2026 bracket #107

Merged
chrisp merged 1 commit from fix/world-cup-simulator-bracket-seeding into main 2026-06-23 21:02:21 +00:00
Owner

Problem

The World Cup Monte Carlo simulator wasn't reflecting the current group stage or simming out the knockout bracket correctly:

  1. The real R32 draw was ignored. Once the admin populated the actual Round-of-32 matchups, the simulator discarded them and re-paired its own simulated group output sequentially (1v2, 3v4, …), so bracket paths from R32 onward didn't match the real tournament.
  2. Group stage could be silently faked. With no groups configured, it invented 12 synthetic groups by slicing the participant list, discarding real standings.

Approach

Reworked the simulator around three regimes:

  • Draw set → simulate the real R32 matchups, advancing through the bracket tree via the canonical ceil(matchNumber/2) rule (matching advanceWinnerTemplate) so sim paths match the admin tooling. Fully-drawn brackets skip the group sim entirely.
  • Groups only → simulate the remaining group matches, then seed the R32 using the official 2026 group-position template + FIFA's exact Annex C best-third-place allocation (the published 495-row table).
  • Neither → futures-seeded bracket fallback, flagged via the result source.

Completed group and knockout matches still lock in real results at every round.

Annex C data

app/lib/fifa-2026-bracket.ts encodes the R32 group-position template (official FIFA matches 73–88 mapped onto DB matchNumbers 1–16 so the ceil(n/2) tree reproduces the real bracket halves) and assignThirdPlaceSlots(). The 495-row third-place allocation is generated deterministically from the published source by scripts/gen-fifa-third-place.mjs into app/lib/fifa-2026-third-place-allocation.ts — no hand-transcription.

Tests

  • Exact Annex C value assertions + a cross-check that the template's eligible-group lists match the table across all 495 combinations.
  • Each regime, plus the partial-draw dedup (no team placed in the R32 twice) and the fully-drawn fast path.
  • Full simulations suite: 643/643 passing; typecheck and lint clean.

🤖 Generated with Claude Code

## Problem The World Cup Monte Carlo simulator wasn't reflecting the current group stage or simming out the knockout bracket correctly: 1. **The real R32 draw was ignored.** Once the admin populated the actual Round-of-32 matchups, the simulator discarded them and re-paired its own simulated group output sequentially (`1v2, 3v4, …`), so bracket paths from R32 onward didn't match the real tournament. 2. **Group stage could be silently faked.** With no groups configured, it invented 12 synthetic groups by slicing the participant list, discarding real standings. ## Approach Reworked the simulator around three regimes: - **Draw set** → simulate the real R32 matchups, advancing through the bracket tree via the canonical `ceil(matchNumber/2)` rule (matching `advanceWinnerTemplate`) so sim paths match the admin tooling. Fully-drawn brackets skip the group sim entirely. - **Groups only** → simulate the remaining group matches, then seed the R32 using the **official 2026 group-position template** + FIFA's **exact Annex C** best-third-place allocation (the published 495-row table). - **Neither** → futures-seeded bracket fallback, flagged via the result `source`. Completed group and knockout matches still lock in real results at every round. ## Annex C data `app/lib/fifa-2026-bracket.ts` encodes the R32 group-position template (official FIFA matches 73–88 mapped onto DB matchNumbers 1–16 so the `ceil(n/2)` tree reproduces the real bracket halves) and `assignThirdPlaceSlots()`. The 495-row third-place allocation is generated deterministically from the published source by `scripts/gen-fifa-third-place.mjs` into `app/lib/fifa-2026-third-place-allocation.ts` — no hand-transcription. ## Tests - Exact Annex C value assertions + a cross-check that the template's eligible-group lists match the table across all 495 combinations. - Each regime, plus the partial-draw dedup (no team placed in the R32 twice) and the fully-drawn fast path. - Full simulations suite: 643/643 passing; typecheck and lint clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
chrisp added 1 commit 2026-06-23 19:16:05 +00:00
Reflect group stage in World Cup sim; seed R32 from real 2026 bracket
All checks were successful
🚀 Deploy / 🧪 Test (pull_request) Successful in 2m53s
🚀 Deploy / ʦ🔍 Typecheck & Lint (pull_request) Successful in 1m19s
🚀 Deploy / 🐳 Build (pull_request) Has been skipped
🚀 Deploy / 🚀 Deploy (pull_request) Has been skipped
🚀 Deploy / 🧪 Test (push) Successful in 3m6s
🚀 Deploy / ʦ🔍 Typecheck & Lint (push) Successful in 1m22s
🚀 Deploy / 🐳 Build (push) Successful in 1m13s
🚀 Deploy / 🚀 Deploy (push) Successful in 13s
6772079e86
The World Cup Monte Carlo simulator ignored the admin-populated knockout
draw and re-paired its own simulated group output sequentially, so bracket
paths from the Round of 32 onward did not match the real tournament. It
also silently invented 12 synthetic groups when none were configured,
discarding real group-stage results.

Rework the simulator around three regimes:
- draw set     → simulate the real R32 matchups, advancing through the
  bracket tree via the canonical ceil(matchNumber/2) rule (matching
  advanceWinnerTemplate) so sim paths match the admin tooling.
- groups only  → simulate remaining group matches, then seed the R32 with
  the official 2026 group-position template + FIFA's exact Annex C
  best-third-place allocation (495-row published table).
- neither      → futures-seeded bracket fallback, flagged via result source.

Completed group and knockout matches still lock in real results at every
round.

New app/lib/fifa-2026-bracket.ts encodes the R32 group-position template
(official FIFA matches 73-88 mapped onto DB matchNumbers 1-16 so the tree
reproduces the real halves) and assignThirdPlaceSlots(). The Annex C table
is generated deterministically by scripts/gen-fifa-third-place.mjs into
app/lib/fifa-2026-third-place-allocation.ts.

Tests assert exact Annex C values, cross-check the template's eligible
groups against all 495 combinations, and cover each regime including the
partial-draw dedup and fully-drawn fast path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
chrisp merged commit 6772079e86 into main 2026-06-23 21:02:21 +00:00
chrisp deleted branch fix/world-cup-simulator-bracket-seeding 2026-06-23 21:02:21 +00:00
Sign in to join this conversation.
No description provided.