From dfc7ac99af20ab40271424951e462c8d9709f801 Mon Sep 17 00:00:00 2001 From: Cal Corum Date: Wed, 26 Nov 2025 22:21:51 -0600 Subject: [PATCH] CLAUDE: Fix runner advancement logic for doubles and hit location MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two related bug fixes for gameplay accuracy: **Backend - play_resolver.py**: - Fixed DOUBLE2 advancement: Runners now advance exactly 2 bases * 1st → 3rd, 2nd → home, 3rd → home * Was incorrectly advancing all runners to home - Fixed DOUBLE3 advancement: Runners now advance exactly 3 bases * All runners score (1st+3=4, 2nd+3=5→4, 3rd+3=6→4) * Updated docstrings for clarity **Frontend - ManualOutcomeEntry.vue**: - Fixed hit location requirement logic * Now requires hit location when runners on base (any outs) * Was incorrectly restricting to only when outs < 2 * Hit location determines runner advancement regardless of outs These fixes ensure accurate Strat-O-Matic gameplay simulation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- backend/app/core/play_resolver.py | 16 ++++++++++------ .../components/Gameplay/ManualOutcomeEntry.vue | 8 +++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/backend/app/core/play_resolver.py b/backend/app/core/play_resolver.py index 22dfb07..9b2ccf6 100644 --- a/backend/app/core/play_resolver.py +++ b/backend/app/core/play_resolver.py @@ -695,22 +695,26 @@ class PlayResolver: return advances def _advance_on_double_2(self, state: GameState) -> list[tuple[int, int]]: - """Calculate runner advancement on double""" + """Calculate runner advancement on DOUBLE2 - all runners advance exactly 2 bases""" advances = [] - # All runners score on double (simplified) + # Runners advance 2 bases: + # 1st -> 3rd, 2nd -> home, 3rd -> home for base, _ in state.get_all_runners(): - advances.append((base, 4)) + final_base = min(base + 2, 4) + advances.append((base, final_base)) return advances def _advance_on_double_3(self, state: GameState) -> list[tuple[int, int]]: - """Calculate runner advancement on double""" + """Calculate runner advancement on DOUBLE3 - all runners advance exactly 3 bases""" advances = [] - # All runners score on double (simplified) + # Runners advance 3 bases (all score from any base) + # 1st -> home (1+3=4), 2nd -> home (2+3=5→4), 3rd -> home for base, _ in state.get_all_runners(): - advances.append((base, 4)) + final_base = min(base + 3, 4) + advances.append((base, final_base)) return advances diff --git a/frontend-sba/components/Gameplay/ManualOutcomeEntry.vue b/frontend-sba/components/Gameplay/ManualOutcomeEntry.vue index 6b713f4..b5c8b0b 100644 --- a/frontend-sba/components/Gameplay/ManualOutcomeEntry.vue +++ b/frontend-sba/components/Gameplay/ManualOutcomeEntry.vue @@ -139,11 +139,9 @@ const needsHitLocation = computed(() => { if (!selectedOutcome.value) return false if (!(outcomesNeedingHitLocation as readonly string[]).includes(selectedOutcome.value)) return false - // Hit location only matters when there are runners on base AND less than 2 outs - // (for fielding choices and runner advancement) - const hasRunnersAndCanAdvance = props.hasRunners && props.outs < 2 - - return hasRunnersAndCanAdvance + // Hit location matters when there are runners on base + // (for determining runner advancement regardless of outs) + return props.hasRunners }) const canSubmitForm = computed(() => {