# Game API Architecture

## Overview

The Game API provides the runtime state management layer for the poker engine—transforming Hand notation into a rich, queryable game state suitable for interactive poker applications. Game serves as the comprehensive rules engine and state manager, handling all validation, player management, chip and pot distribution, timing, and analytics throughout the whole game lifecycle.

## Architecture Pattern

```
Hand Data → Game Constructor → Runtime State → Query/Validate Operations
```

### Key Principles

1. **Rules Engine**: Game owns all poker logic, validation, and rule enforcement
2. **State Management**: Transforms immutable Hand notation into rich runtime state
3. **Validation Authority**: Primary source for action validation and game rule checking
4. **Analytics Provider**: Real-time game metrics, timing, and player state queries
5. **Deterministic State**: Identical Hand inputs always produce identical Game states
6. **Clear Boundaries**: Game = rules & state, Hand = data notation, Command = action generation

## Game Categories

### State Construction

- `Poker.Game(hand: Hand, actions?: Action[])` → Game with optional custom actions

### State Query Operations

#### Player Management

- `Poker.Game.getPlayerIndex(game: Game, playerIdentifier)` → 0-based player index (-1 if not found)
- `Poker.Game.hasActed(game: Game, playerIdentifier)` → Check if player acted this round

#### Game State Analysis

- `Poker.Game.getTimeLeft(game: Game)` → Remaining decision time in milliseconds
- `Poker.Game.getElapsedTime(game: Game)` → Time since last action in milliseconds

#### Analytics Operations

- `Poker.Stats(game: Game)` → Returns one row per player per street; multiple actions on a street are merged into a single row.
- `Poker.StatsRow(game: Game, playerId: string, street: Street, streetStats: PlayerStreetStats)` → Build stats row in canonical order

### Validation Operations

- `Poker.Game.canApplyAction(game: Game, action: Action)` → Comprehensive rule validation

### State Modification Operations

- `Poker.Game.applyAction(game: Game, action: Action)` → Apply action and return mutated game argument
- `Poker.Game.finish(game: Game, hand: Hand)` → Extract finishing data and update hand with final state

## Implementation Contract

### Rules Engine Contract

Game methods MUST:

1. **Own** all game logic and rule validation
2. **Transform** Hand notation into queryable runtime state
3. **Validate** all actions against comprehensive poker rules
4. **Maintain** deterministic state from Hand data
5. **Never** modify Hand data directly

### Input/Output Contract

- **Input**: Accepts Hand objects and optional Action arrays
- **Output**: Returns primitive values, Game state, or null for not found
- **Side Effects**: None for query methods
- **Validation**: Comprehensive rule checking for all poker constraints

### Clear Separation of Concerns

- **Game Owns**: All game logic, rules, validation, state queries, analytics
- **Hand Owns**: Data notation, serialization, action sequences
- **Command Owns**: Action generation from user input

### Integration Points

- **Hand Namespace**: Receives Hand data for state construction
- **Command Namespace**: Validates actions generated by Commands
- **Core Engine**: Uses internal validators, processors, and utilities

## Test-Driven Development Implementation

### Test Structure

Tests organized by functional categories:

- `core-contract.test.ts` - Rules engine contracts and state determinism
- `construction.test.ts` - Game constructor with various Hand inputs
- `player-management.test.ts` - getPlayerIndex, hasActed
- `state-analysis.test.ts` - isShowdown, timing methods, finish method, getStats analytics
- `validation.test.ts` - canApplyAction comprehensive rule checking
- `state-modification.test.ts` - applyAction state updates
- `edge-cases.test.ts` - Boundary conditions and impossible values with valid types
- `integration.test.ts` - Complex multi-method scenarios

### Test Fixtures

- `fixtures/baseGame.ts` - Three different complex game states as stable testing base
- All fixtures created from validated Hand objects to ensure realistic states

### Testing Principles

1. **Rules Verification**: Test all poker rule validations thoroughly
2. **State Determinism**: Same Hand always produces same Game state
3. **Query Accuracy**: All queries return correct information
4. **Validation Coverage**: Test both valid and invalid actions
5. **No Side Effects**: Query methods never modify state
6. **Integration Testing**: Complex scenarios with multiple operations
7. **Boundary Testing**: Focus on logical impossibilities, not type errors

### Key Method Test Scenarios

#### Constructor Testing

- Verify Hand to Game transformation accuracy
- Test with various Hand variants (NT, FT, F7S)
- Ensure action replay builds correct state
- Validate optional actions parameter handling
- Test with minimal Hand data

#### canApplyAction() Testing

- Turn order validation (correct player acting)
- Stack requirement checks (sufficient chips)
- Betting minimum enforcement
- Raise size validation
- Check/call availability based on game state
- Showdown-specific action validation
- Invalid action rejection

#### Timing Methods Testing

- getTimeLeft() countdown accuracy
- getElapsedTime() elapsed timer accuracy
- Handling of missing timestamps
- Zero returns for no time limit

#### Player Management Testing

- Return -1 for non-existent player indices
- Return -1 for unknown player names
- Correct index for valid identifiers
- hasActed() returns false for invalid players

#### Stats Analytics Testing

- getStats() returns formatted string matrix for database insertion
- Each row represents player-street combination
- Values formatted as SQL-ready strings

#### State Modification Testing (applyAction)

- Mutates game state correctly
- Handles player actions (fold, call, bet, raise)
- Handles dealer actions (deal cards, advance streets)
- Throws for invalid actions
- Updates all relevant game properties

#### Finish Method Testing

- Extracts finishing data when game complete
- Returns unchanged hand when game not complete
- Calculates winnings correctly
- Preserves chip continuity
- Handles rake extraction

## Critical Implementation Details

### State Construction Pattern

```typescript
const game = Poker.Game(hand);
const gameWithCustom = Poker.Game(hand, customActions);
```

### Player Resolution Convention

All player lookup methods follow consistent pattern:

- Valid player → return correct index (0-based)
- Invalid index → return -1
- Unknown name → return -1
- Never throw for missing players in query methods

### Validation Comprehensiveness

canApplyAction() validates:

1. Turn validation (correct player acting)
2. Action format validation
3. Stack sufficiency checks
4. Minimum bet/raise requirements
5. Game state appropriateness
6. Variant-specific rules
7. Street-specific constraints

### Showdown Detection Logic

```typescript
isShowdown = isFinalStreet && playersRemaining > 1 && bettingComplete;
```

### Timing Calculations

```typescript
getTimeLeft() = timeLimit - (now - lastActionTimestamp);
getElapsedTime() = now - lastActionTimestamp;
```

## Error Handling Philosophy

Game namespace focuses on logical errors with valid types:

1. **Out of Bounds**: Player index beyond array length → return -1
2. **Impossible Values**: Negative stacks, invalid amounts → handle gracefully
3. **State Inconsistencies**: Detect impossible game states
4. **Rule Violations**: Clear messages about broken rules
5. **Type Safety**: Let TypeScript handle type mismatches

## Performance Considerations

- **Lazy Evaluation**: Compute expensive state only when needed
- **Cached Computations**: Store frequently accessed derived state
- **Efficient Lookups**: Optimize player resolution
- **Minimal Cloning**: Avoid unnecessary object copies

## Testing Strategy

### Unit Tests

- Each Game method tested in isolation
- Verify correct integration with core utilities
- Test determinism and side-effect freedom
- Validate boundary conditions

### Integration Tests

- Multi-method operations
- Complex game progression scenarios
- Showdown resolution flows
- Timing interactions with validation

### Property-Based Tests

- Invariants: Deterministic state from same Hand
- Consistency: Related methods return consistent information
- Completeness: All valid actions accepted, invalid rejected

## Validation Test Matrix

### Action Types to Validate

- Player actions: fold, check, call, bet, raise, all-in
- Dealer actions: deal cards, advance streets
- Showdown actions: show, muck cards
- Meta actions: messages, timeouts

### Constraints to Test

- Turn order enforcement
- Stack limits validation
- Minimum bet requirements
- Street progression rules
- Showdown reveal requirements

## Edge Cases Focus

### Value Boundary Testing (not type testing)

- Player index at array bounds (length, length+1, -1)
- Empty player arrays
- Zero or negative time limits
- Amounts at stack limits
- Actions with empty strings
- Null vs undefined in optional fields

### State Consistency

- Game without players
- Showdown with one player
- Negative pot values
- Invalid button positions
- Contradictory state flags
