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>
159 lines
6.3 KiB
Markdown
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
|