Implement uncapped hit decision tree (SINGLE_UNCAPPED, DOUBLE_UNCAPPED) #5

Closed
opened 2026-02-11 20:09:35 +00:00 by cal · 0 comments
Owner

Summary

The play resolver currently stubs uncapped hits (SINGLE_UNCAPPED / DOUBLE_UNCAPPED) by treating them as SINGLE_1 and DOUBLE_2 respectively. These outcomes need proper hit-location-based runner advancement logic.

Current Behavior

  • SINGLE_UNCAPPED (si(cf) on pitching card) → falls through to _advance_on_single_1() regardless of hit location
  • DOUBLE_UNCAPPED (do(cf) on pitching card) → falls through to _advance_on_double_2() regardless of hit location

See backend/app/core/play_resolver.py:523 and :591

Expected Behavior

Uncapped hits should resolve runner advancement based on hit location:

SINGLE_UNCAPPED

  • Business rule: hit_location matters when R1, R2, or both are on base
  • Outfield hits (LF/CF/RF) → different advancement patterns based on where ball lands
  • Infield singles (rare) → standard SINGLE_1 advancement

DOUBLE_UNCAPPED

  • Business rule: hit_location matters when R1 is on base
  • Down the line vs gap hits → different runner advancement

Runner advancement patterns should follow the Strat-O-Matic uncapped hit chart rules where the fielder location determines whether runners advance extra bases or hold.

Implementation Notes

  • The validation logic is already in place (raises ValueError if hit_location is missing when required)
  • hit_location is passed into resolve_outcome() and available in both code paths
  • Valid hit locations: 1B, 2B, SS, 3B, LF, CF, RF, P, C
  • Need new private methods _resolve_uncapped_single() and _resolve_uncapped_double()
  • Should include truth-table style tests following existing pattern in backend/tests/unit/core/truth_tables/

Files

  • backend/app/core/play_resolver.py - Main implementation (lines 510-607)
  • backend/tests/unit/core/truth_tables/ - Test location

References

  • Existing advancement methods: _advance_on_single_1, _advance_on_single_2, _advance_on_double_2, _advance_on_double_3
  • Implementation plan: .claude/implementation/phase-3.5-polish-stats.md:961-1019
  • Config: PlayOutcome.is_uncapped() helper already exists
## Summary The play resolver currently stubs uncapped hits (`SINGLE_UNCAPPED` / `DOUBLE_UNCAPPED`) by treating them as `SINGLE_1` and `DOUBLE_2` respectively. These outcomes need proper hit-location-based runner advancement logic. ## Current Behavior - `SINGLE_UNCAPPED` (si(cf) on pitching card) → falls through to `_advance_on_single_1()` regardless of hit location - `DOUBLE_UNCAPPED` (do(cf) on pitching card) → falls through to `_advance_on_double_2()` regardless of hit location See `backend/app/core/play_resolver.py:523` and `:591` ## Expected Behavior Uncapped hits should resolve runner advancement based on **hit location**: ### SINGLE_UNCAPPED - Business rule: hit_location matters when R1, R2, or both are on base - Outfield hits (LF/CF/RF) → different advancement patterns based on where ball lands - Infield singles (rare) → standard SINGLE_1 advancement ### DOUBLE_UNCAPPED - Business rule: hit_location matters when R1 is on base - Down the line vs gap hits → different runner advancement Runner advancement patterns should follow the Strat-O-Matic uncapped hit chart rules where the fielder location determines whether runners advance extra bases or hold. ## Implementation Notes - The validation logic is already in place (raises ValueError if hit_location is missing when required) - `hit_location` is passed into `resolve_outcome()` and available in both code paths - Valid hit locations: `1B, 2B, SS, 3B, LF, CF, RF, P, C` - Need new private methods `_resolve_uncapped_single()` and `_resolve_uncapped_double()` - Should include truth-table style tests following existing pattern in `backend/tests/unit/core/truth_tables/` ## Files - `backend/app/core/play_resolver.py` - Main implementation (lines 510-607) - `backend/tests/unit/core/truth_tables/` - Test location ## References - Existing advancement methods: `_advance_on_single_1`, `_advance_on_single_2`, `_advance_on_double_2`, `_advance_on_double_3` - Implementation plan: `.claude/implementation/phase-3.5-polish-stats.md:961-1019` - Config: `PlayOutcome.is_uncapped()` helper already exists
cal closed this issue 2026-02-11 20:10:37 +00:00
Sign in to join this conversation.
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: cal/strat-gameplay-webapp#5
No description provided.