Commit Graph

6 Commits

Author SHA1 Message Date
Cal Corum
a696473d0a CLAUDE: Integrate flyball advancement with RunnerAdvancement system
Major Phase 2 refactoring to consolidate runner advancement logic:

**Flyball System Enhancement**:
- Add FLYOUT_BQ variant (medium-shallow depth)
- 4 flyball types with clear semantics: A (deep), B (medium), BQ (medium-shallow), C (shallow)
- Updated helper methods to include FLYOUT_BQ

**RunnerAdvancement Integration**:
- Extend runner_advancement.py to handle both groundballs AND flyballs
- advance_runners() routes to _advance_runners_groundball() or _advance_runners_flyball()
- Comprehensive flyball logic with proper DECIDE mechanics per flyball type
- No-op movements recorded for state recovery consistency

**PlayResolver Refactoring**:
- Consolidate all 4 flyball outcomes to delegate to RunnerAdvancement (DRY)
- Eliminate duplicate flyball resolution code
- Rename helpers for clarity: _advance_on_single_1/_advance_on_single_2 (was _advance_on_single)
- Fix single/double advancement logic for different hit types

**State Recovery Fix**:
- Fix state_manager.py game recovery to build LineupPlayerState objects properly
- Use get_lineup_player() helper to construct from lineup data
- Correctly track runners in on_first/on_second/on_third fields (matches Phase 2 model)

**Database Support**:
- Add runner tracking fields to play data for accurate recovery
- Include batter_id, on_first_id, on_second_id, on_third_id, and *_final fields

**Type Safety Improvements**:
- Fix lineup_id access throughout runner_advancement.py (was accessing on_first directly, now on_first.lineup_id)
- Make current_batter_lineup_id non-optional (always set by _prepare_next_play)
- Add type: ignore for known SQLAlchemy false positives

**Documentation**:
- Update CLAUDE.md with comprehensive flyball documentation
- Add flyball types table, usage examples, and test coverage notes
- Document differences between groundball and flyball mechanics

**Testing**:
- Add test_flyball_advancement.py with 21 flyball tests
- Coverage: all 4 types, DECIDE scenarios, no-op movements, edge cases

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 17:04:23 -05:00
Cal Corum
76e24ab22b CLAUDE: Refactor ManualOutcomeSubmission to use PlayOutcome enum + comprehensive documentation
## Refactoring
- Changed `ManualOutcomeSubmission.outcome` from `str` to `PlayOutcome` enum type
- Removed custom validator (Pydantic handles enum validation automatically)
- Added direct import of PlayOutcome (no circular dependency due to TYPE_CHECKING guard)
- Updated tests to use enum values while maintaining backward compatibility

Benefits:
- Better type safety with IDE autocomplete
- Cleaner code (removed 15 lines of validator boilerplate)
- Backward compatible (Pydantic auto-converts strings to enum)
- Access to helper methods (is_hit(), is_out(), etc.)

Files modified:
- app/models/game_models.py: Enum type + import
- tests/unit/config/test_result_charts.py: Updated 7 tests + added compatibility test

## Documentation
Created comprehensive CLAUDE.md files for all backend/app/ subdirectories to help future AI agents quickly understand and work with the code.

Added 8,799 lines of documentation covering:
- api/ (906 lines): FastAPI routes, health checks, auth patterns
- config/ (906 lines): League configs, PlayOutcome enum, result charts
- core/ (1,288 lines): GameEngine, StateManager, PlayResolver, dice system
- data/ (937 lines): API clients (planned), caching layer
- database/ (945 lines): Async sessions, operations, recovery
- models/ (1,270 lines): Pydantic/SQLAlchemy models, polymorphic patterns
- utils/ (959 lines): Logging, JWT auth, security
- websocket/ (1,588 lines): Socket.io handlers, real-time events
- tests/ (475 lines): Testing patterns and structure

Each CLAUDE.md includes:
- Purpose & architecture overview
- Key components with detailed explanations
- Patterns & conventions
- Integration points
- Common tasks (step-by-step guides)
- Troubleshooting with solutions
- Working code examples
- Testing guidance

Total changes: +9,294 lines / -24 lines
Tests: All passing (62/62 model tests, 7/7 ManualOutcomeSubmission tests)
2025-10-31 16:03:54 -05:00
Cal Corum
e2f1d6079f CLAUDE: Implement Week 7 Task 6 - PlayResolver Integration with RunnerAdvancement
Major Refactor: Outcome-First Architecture
- PlayResolver now accepts league_id and auto_mode in constructor
- Added core resolve_outcome() method - all resolution logic in one place
- Added resolve_manual_play() wrapper for manual submissions (primary)
- Added resolve_auto_play() wrapper for PD auto mode (rare)
- Removed SimplifiedResultChart (obsolete with new architecture)
- Removed play_resolver singleton

RunnerAdvancement Integration:
- All groundball outcomes (GROUNDBALL_A/B/C) now use RunnerAdvancement
- Proper DP probability calculation with positioning modifiers
- Hit location tracked for all relevant outcomes
- 13 result types fully integrated from advancement charts

Game State Updates:
- Added auto_mode field to GameState (stored per-game)
- Updated state_manager.create_game() to accept auto_mode parameter
- GameEngine now uses state.auto_mode to create appropriate resolver

League Configuration:
- Added supports_auto_mode() to BaseGameConfig
- SbaConfig: returns False (no digitized cards)
- PdConfig: returns True (has digitized ratings)
- PlayResolver validates auto mode support and raises error for SBA

Play Results:
- Added hit_location field to PlayResult
- Groundballs include location from RunnerAdvancement
- Flyouts track hit_location for tag-up logic (future)
- Other outcomes have hit_location=None

Testing:
- Completely rewrote test_play_resolver.py for new architecture
- 9 new tests covering initialization, strikeouts, walks, groundballs, home runs
- All 9 tests passing
- All 180 core tests still passing (1 pre-existing failure unrelated)

Terminal Client:
- No changes needed - defaults to manual mode (auto_mode=False)
- Perfect for human testing of manual submissions

This completes Week 7 Task 6 - the final task of Week 7!
Week 7 is now 100% complete with all 8 tasks done.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 08:20:52 -05:00
Cal Corum
9245b4e008 CLAUDE: Implement Week 7 Task 3 - Result chart abstraction and PD auto mode
Core Implementation:
- Added ResultChart abstract base class with get_outcome() method
- Implemented calculate_hit_location() helper for hit distribution
  - 45% pull, 35% center, 20% opposite field
  - RHB pulls left, LHB pulls right
  - Groundballs → infield positions, flyouts → outfield positions
- Added PlayOutcome.requires_hit_location() helper method
  - Returns True for groundballs and flyouts only

Manual Mode Support:
- Added ManualResultChart (passthrough for interface completeness)
- Manual mode doesn't use result charts - players submit directly
- Added ManualOutcomeSubmission model for WebSocket submissions
  - Validates PlayOutcome enum values
  - Validates hit location positions (1B, 2B, SS, 3B, LF, CF, RF, P, C)

PD Auto Mode Implementation:
- Implemented PdAutoResultChart for automated outcome generation
  - Coin flip (50/50) to choose batting or pitching card
  - Gets rating for correct handedness matchup
  - Builds cumulative distribution from rating percentages
  - Rolls 1d100 to select outcome
  - Calculates hit location using handedness and pull rates
- Maps rating fields to PlayOutcome enum:
  - Common: homerun, triple, doubles, singles, walks, strikeouts
  - Batting-specific: lineouts, popouts, flyout variants, groundout variants
  - Pitching-specific: uncapped singles/doubles, flyouts by location
- Proper error handling when card data missing

Testing:
- Created 21 comprehensive unit tests (all passing)
- Helper function tests (calculate_hit_location)
- PlayOutcome helper tests (requires_hit_location)
- ManualResultChart tests (NotImplementedError)
- PdAutoResultChart tests:
  - Coin flip distribution (~50/50)
  - Handedness matchup selection
  - Cumulative distribution building
  - Outcome selection from probabilities
  - Hit location calculation
  - Error handling for missing cards
  - Statistical distribution verification (1000 trials)
- ManualOutcomeSubmission validation tests
  - Valid/invalid outcomes
  - Valid/invalid hit locations
  - Optional location handling

Deferred to Future Tasks:
- PlayResolver integration (Phase 6 - Week 7 Task 3B)
- Terminal client manual outcome command (Phase 8)
- WebSocket handlers for manual submissions (Week 7 Task 6)
- Runner advancement logic using hit locations (Week 7 Task 4)

Files Modified:
- app/config/result_charts.py: Added base class, auto mode, and helpers
- app/models/game_models.py: Added ManualOutcomeSubmission model
- tests/unit/config/test_result_charts.py: 21 comprehensive tests

All tests passing, no regressions.
2025-10-30 12:42:41 -05:00
Cal Corum
6880b6d5ad CLAUDE: Complete Week 6 - granular PlayOutcome integration and metadata support
- Renamed check_d20 → chaos_d20 throughout dice system
- Expanded PlayOutcome enum with granular variants (SINGLE_1/2, DOUBLE_2/3, GROUNDBALL_A/B/C, etc.)
- Integrated PlayOutcome from app.config into PlayResolver
- Added play_metadata support for uncapped hit tracking
- Updated all tests (139/140 passing)

Week 6: 100% Complete - Ready for Phase 3

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 20:29:06 -05:00
Cal Corum
5d5c13f2b8 CLAUDE: Implement Week 6 league configuration and play outcome systems
Week 6 Progress: 75% Complete

## Components Implemented

### 1. League Configuration System 
- Created BaseGameConfig abstract class for league-agnostic rules
- Implemented SbaConfig and PdConfig with league-specific settings
- Immutable configs (frozen=True) with singleton registry
- 28 unit tests, all passing

Files:
- backend/app/config/base_config.py
- backend/app/config/league_configs.py
- backend/tests/unit/config/test_league_configs.py

### 2. PlayOutcome Enum 
- Universal enum for all play outcomes (both SBA and PD)
- Helper methods: is_hit(), is_out(), is_uncapped(), is_interrupt()
- Supports standard hits, uncapped hits, interrupt plays, ballpark power
- 30 unit tests, all passing

Files:
- backend/app/config/result_charts.py
- backend/tests/unit/config/test_play_outcome.py

### 3. Player Model Refinements 
- Fixed PdPlayer.id field mapping (player_id → id)
- Improved field docstrings for image types
- Fixed position checking logic in SBA helper methods
- Added safety checks for missing image data

Files:
- backend/app/models/player_models.py (updated)

### 4. Documentation 
- Updated backend/CLAUDE.md with Week 6 section
- Documented card-based resolution mechanics
- Detailed config system and PlayOutcome usage

## Architecture Decisions

1. **Card-Based Resolution**: Both SBA and PD use same mechanics
   - 1d6 (column) + 2d6 (row) + 1d20 (split resolution)
   - PD: Digitized cards with auto-resolution
   - SBA: Manual entry from physical cards

2. **Immutable Configs**: Prevent accidental modification using Pydantic frozen

3. **Universal PlayOutcome**: Single enum for both leagues reduces duplication

## Testing
- Total: 58 tests, all passing
- Config tests: 28
- PlayOutcome tests: 30

## Remaining Work (25%)
- Update dice system (check_d20 → chaos_d20)
- Integrate PlayOutcome into PlayResolver
- Add Play.metadata support for uncapped hits

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 22:46:12 -05:00