strat-gameplay-webapp/.claude/implementation/GROUNDBALL_CHART_REFERENCE.md
Cal Corum fb282a5e54 CLAUDE: Fix critical X-Check bugs and improve dice rolling
Fixed two critical bugs in Phase 3D X-Check implementation plus
improved dice audit trail for better tracking.

BUG #1: on_base_code Mapping Error (Sequential vs Bit Field)
============================================================
The implementation incorrectly treated on_base_code as a bit field
when it is actually a sequential lookup mapping.

WRONG (bit field):
  Code 3 (0b011) → R1 + R2
  Code 4 (0b100) → R3 only

CORRECT (sequential):
  Code 3 → R3 only
  Code 4 → R1 + R2

Fixed:
- build_advancement_from_code() decoder (sequential mapping)
- build_flyball_advancement_with_error() decoder (sequential mapping)
- 13 test on_base_code values (3↔4 corrections)
- Updated documentation to clarify NOT a bit field

BUG #2: Table Data Not Matching Official Charts
================================================
7 table entries in G1_ADVANCEMENT_TABLE and G2_ADVANCEMENT_TABLE
did not match the official rulebook charts provided by user.

Fixed table entries:
- G1 Code 1, Infield In: Changed Result 3 → 2
- G1 Code 3, Normal: Changed Result 13 → 3
- G1 Code 3, Infield In: Changed Result 3 → 1
- G1 Code 4, Normal: Changed Result 3 → 13
- G1 Code 4, Infield In: Changed Result 4 → 2
- G2 Code 3, Infield In: Changed Result 3 → 1
- G2 Code 4, Normal: Changed Result 5 → 4

Also fixed 7 test expectations to match corrected tables.

IMPROVEMENT: Better Dice Audit Trail
=====================================
Updated _resolve_x_check() in PlayResolver to use proper
dice_system.roll_fielding() instead of manual die rolling.

Benefits:
- All dice tracked in audit trail (roll_id, timestamp, position)
- Automatic error_total calculation (no manual 3d6 addition)
- Consistent with codebase patterns
- Position recorded for historical analysis

Testing:
- All 59 X-Check advancement tests passing (100%)
- All 9 PlayResolver tests passing (100%)
- All table entries validated against official charts
- Complete codebase scan: no bit field operations found

Files modified:
- backend/app/core/x_check_advancement_tables.py
- backend/tests/unit/core/test_x_check_advancement_tables.py
- backend/app/core/play_resolver.py
- .claude/implementation/PHASE_3D_CRITICAL_FIX.md (documentation)
- .claude/implementation/GROUNDBALL_CHART_REFERENCE.md (new)
- .claude/implementation/XCHECK_TEST_VALIDATION.md (new)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 23:09:16 -06:00

159 lines
6.3 KiB
Markdown

# Groundball Chart Reference - Official Source of Truth
**Source**: User-provided images from official rulebook charts
**Date Created**: 2025-11-02
**Purpose**: Comprehensive reference for validating all groundball test expectations
---
## GroundballResultType Reference (1-13)
```
1. BATTER_OUT_RUNNERS_HOLD
2. DOUBLE_PLAY_AT_SECOND - Batter out, runner on 1st out - double play! Other runners advance 1 base
3. BATTER_OUT_RUNNERS_ADVANCE
4. BATTER_SAFE_FORCE_OUT_AT_SECOND - Batter safe, runner on 1st forced out at 2nd. Other runners advance 1 base
5. HIT_TO_2B/SS - Batter out, runners advance 1 base. Hit anywhere else: batter out, runners hold
6. HIT_TO_1B/2B - Batter out, runners advance 1 base. Hit anywhere else: batter out, runners hold
7. BATTER_OUT_FORCED_ONLY - Batter out, runner holds (unless forced)
8. BATTER_OUT_FORCED_ONLY_ALT - Batter out, runner holds (unless forced)
9. LEAD_HOLDS_TRAIL_ADVANCES - Batter out, runner on 3rd holds, runner on 1st advances 1 base
10. DOUBLE_PLAY_HOME_TO_FIRST - Home to first double play, other runners advance
11. BATTER_SAFE_LEAD_OUT - Batter safe, lead runner is out, other runners advance 1 base
12. DECIDE - Hit to 1b/2b: batter is out, runners advance. Hit to 3b: batter is out, runners hold. Hit to ss/p/c: chance for DECIDE
13. CONDITIONAL_DOUBLE_PLAY - Hit to c/3b: double play at 3rd and 2nd base, batter safe. Otherwise: double play at 2nd and 1st base
```
---
## G1 Chart (Groundball Type A - Fast Grounder)
### Simplified View from Image #1
| Bases Occupied | Infield Normal | Infield In |
|----------------|----------------|------------|
| Empty | 1 | N/A |
| 1st | 2 | 2 |
| 2nd | 12 | 12 |
| 3rd | 3 | 1 |
| 1st & 2nd | 13 | 2 |
| 1st & 3rd | 2 | 1 |
| 2nd & 3rd | 3 | 1 |
| Loaded | 2 | 10 |
**Notes**:
- Image #1 appears to show a simplified chart with one result per (base situation, defensive position)
- May represent GBA (Groundball A) specifically
- Need clarification: Are GBB and GBC different for G1, or is G1 always the same result?
---
## G2 Chart (Groundball Type B - Medium Grounder)
### Simplified View from Image #2
| Bases Occupied | Infield Normal | Infield In |
|----------------|----------------|------------|
| Empty | 1 | N/A |
| 1st | 4 | 4 |
| 2nd | 12 | 12 |
| 3rd | 5 | 1 |
| 1st & 2nd | 4 | 4 |
| 1st & 3rd | 4 | 1 |
| 2nd & 3rd | 5 | 1 |
| Loaded | 4 | 11 |
---
## G3 Chart (Groundball Type C - Slow Grounder)
### Simplified View from Image #3
| Bases Occupied | Infield Normal | Infield In |
|----------------|----------------|------------|
| Empty | 1 | N/A |
| 1st | 3 | 3 |
| 2nd | 12 | 3 |
| 3rd | 3 | DECIDE |
| 1st & 2nd | 3 | 3 |
| 1st & 3rd | 3 | 3 |
| 2nd & 3rd | 3 | DECIDE |
| Loaded | 3 | 11 |
**Note**: "DECIDE" in chart may map to Result 12 (DECIDE_OPPORTUNITY)
---
## Detailed Infield Back Chart (Image #4)
This appears to be a more detailed breakdown showing GBA, GBB, GBC variations:
| Bases Occupied | GBA | GBB | GBC | Notes |
|----------------|-----|-----|-----|-------|
| Empty | 1 | 1 | 1 | Batter out, runners hold |
| 1st | 2 | 4 | 3 | GBA: DP. GBB: Batter safe, force out at 2nd. GBC: Batter out, advance |
| 2nd | 6 | 6 | 3 | GBA/B: Hit to right side conditional. GBC: Advance |
| 3rd | 5 | 5 | 3 | GBA/B: Hit to middle infield conditional. GBC: Advance |
| 1st & 2nd | 2 | 4 | 3 | GBA: DP. GBB: Batter safe, force. GBC: Advance |
| 1st & 3rd | 2 | 4 | 3 | Same as 1st only |
| 2nd & 3rd | 5 | 5 | 3 | GBA/B: Conditional middle IF. GBC: Advance |
| Loaded | 2 | 4 | 3 | GBA: DP. GBB: Batter safe, force. GBC: R3 holds, R1 advances |
---
## Detailed Infield In Chart (Image #5)
| Bases Occupied | GBA | GBB | GBC | Notes |
|----------------|-----|-----|-----|-------|
| 3rd | 7 | 1 | 8 | Hit to 1b/2b: runners advance. Hit to 3b: hold. ss/p/c: DECIDE |
| 1st & 3rd | 7 | 9 | 8 | GBB: Lead holds, trail advances |
| 2nd & 3rd | 7 | 1 | 8 | Hit to c/3b: double play at 3rd and 2nd |
| Loaded | 10 | 11 | 11 | GBA: DP home to 1st. GBB/C: Batter safe, lead out |
---
## Questions for Validation
1. **Chart Relationship**:
- Are Images #1, #2, #3 showing GBA results specifically?
- Or are they showing a simplified "most common" result?
- Do G1/G2/G3 have different results for GBA/GBB/GBC internally?
2. **Mapping GBA/GBB/GBC to G1/G2/G3**:
- Does G1 always use GBA column from detailed chart?
- Does G2 always use GBB column?
- Does G3 always use GBC column?
- Or is the relationship different?
3. **Test Naming Convention**:
- Current tests use outcome names: GROUNDBALL_A, GROUNDBALL_B, GROUNDBALL_C
- Do these map to: G1=GBA, G2=GBB, G3=GBC?
- Or to: G1/G2/G3 (which then have internal GBA/GBB/GBC logic)?
---
## Current Understanding (To Be Validated)
Based on the code in `runner_advancement.py`, it appears:
- Tests use `PlayOutcome.GROUNDBALL_A/B/C`
- Code maps these to `gb_letter = 'A', 'B', or 'C'`
- Code has charts for "Infield Back" and "Infield In"
- Code selects result based on (gb_letter, base_situation, defensive_position)
**Hypothesis**:
- The detailed charts (Images #4 and #5) show the actual GBA/GBB/GBC breakdown
- The G1/G2/G3 simplified charts (Images #1, #2, #3) might be showing a different categorization
- OR they might be showing just one column from the detailed charts
**Need clarification from user** before proceeding with test fixes.
---
## Next Steps
1. ✅ Transcribe all charts (DONE)
2. ⏳ Get user clarification on chart relationship
3. ⏳ Map each current test to correct expected result
4. ⏳ Fix all test expectations
5. ⏳ Verify all 59 tests pass with correct expectations