Skip to content

Inline live broadcast, win-probability curve, and shot-location sampling - #7

Open
amanzav wants to merge 1 commit into
mainfrom
sim
Open

amanzav wants to merge 1 commit into
mainfrom
sim

Conversation

@amanzav

@amanzav amanzav commented Jun 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

Turns the single-game simulator into a live broadcast experience and makes the simulation richer with real shot placement and a model-derived win-probability curve.

Backend (simulation.py, tendency_profile.py)

  • Shot-location sampling. Each simulated field goal now records a concrete court zone (shot_zone_basic / shot_zone_area) sampled from the player's real shot chart (TendencyProfile.shot_zone_weights). Pre-tracking seasons / players with no observed chart fall back to a disclosed league-average split. Consumes no RNG when no zones exist, so seeded games stay byte-identical.
  • Win-probability curve. New win_probability per game — an absorbing-barrier Markov chain over (score_a, score_b, possession) whose per-possession distributions come from each player's tendency profile. Pinned to 1.0/0.0 only once a player actually reaches 21 (no premature certainty).

Frontend

  • Inline BroadcastStrip replaces the tip-off overlay + collapsible play-by-play: live floor playback, scoreboard, odds graph, final shot-chart comparison, and the running wire feed — scrolled into view on each run.
  • Shared extractions: lib/court (court geometry), lib/liveGame (enrich/resolve/format helpers), lib/shotEfficiency (FG% color ramp + zone grading), and the useLiveGame hook.
  • Head-to-head comparison panel now pinned to the bottom of the page.

Testing

  • pytest backend/tests/test_simulation.py backend/tests/test_tendency_profile.py — 38 passed
  • npx tsc -b --noEmit — clean

Review notes

A /code-review pass surfaced a few follow-ups worth tracking (not blocking this PR):

  • The win-probability possession distribution doesn't fully normalize and diverges slightly from _simulate_possession (raw vs. capped foul rate; foul not scaled by (1 - turnover)).
  • Duplicate efficiencyColor/grading helpers still live in ShotChartSheet.tsx and Simulator.tsx and could import from the new lib/shotEfficiency.
  • OddsGraph rebuilds its SVG paths every animation frame (could be memoized).

🤖 Generated with Claude Code

@vercel

vercel Bot commented Jun 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hoopvision Ready Ready Preview, Comment Jun 13, 2026 12:16am

…ampling

Backend:
- Sample a concrete court zone for each simulated field goal from the player's
  real shot chart (TendencyProfile.shot_zone_weights), falling back to a
  disclosed league-average split for pre-tracking seasons; consumes no RNG when
  absent so seeded games stay byte-identical.
- Add a model-derived win-probability curve per game: an absorbing-barrier
  Markov chain over (score_a, score_b, possession) using each player's tendency
  profile, pinned to 1/0 only once a player reaches 21.

Frontend:
- Replace the tip-off overlay + collapsible play-by-play with an inline
  BroadcastStrip: live floor playback, scoreboard, odds graph, shot-chart
  comparison, and the running wire feed, scrolled into view on each run.
- Extract shared court geometry (lib/court), live-game helpers (lib/liveGame),
  shot-efficiency color ramp (lib/shotEfficiency), and the useLiveGame hook.
- Pin the head-to-head comparison panel to the bottom of the page.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant