Commit Graph

10 Commits

Author SHA1 Message Date
Cal Corum
cbc1da3c03 Add visibility filter for client-safe game state views
SECURITY: Implement hidden information filtering to prevent cheating.

- Create VisibleGameState, VisiblePlayerState, VisibleZone models
- get_visible_state(game, player_id): filtered view for a player
- get_spectator_state(game): filtered view for spectators

Hidden Information (NEVER exposed):
  - Opponent's hand contents (count only)
  - All deck contents and order
  - All prize card contents
  - Energy deck order

Public Information (always visible):
  - Active and benched Pokemon (full details)
  - Discard piles (full contents)
  - Energy zone (available energy)
  - Scores, turn info, phase
  - Stadium in play

- 44 security-critical tests verifying no information leakage
- Tests check JSON serialization for hidden card ID leaks
- Also adds test for configurable burn damage

Completes HIGH-008 and TEST-012 from PROJECT_PLAN.json
Updates security checklist: 4/5 items now verified
2026-01-25 13:11:06 -06:00
Cal Corum
eef857e972 Add turn manager with phase state machine and between-turn effects
- Implement TurnManager class for turn/phase state machine
- Phase transitions: SETUP -> DRAW -> MAIN -> ATTACK -> END
- Turn start: reset counters, draw card, flip energy (Pokemon Pocket style)
- Turn end: apply status damage (poison/burn), check recovery (sleep/burn flip)
- Between-turn paralysis auto-removal
- Knockout processing with scoring and forced action setup
- Integration with win condition checking (deck-out, no Pokemon, turn limit)
- 60 tests covering all functionality
- 644 total core tests passing at 97% coverage

Completes HIGH-007 and TEST-011 from PROJECT_PLAN.json
Week 4 (Game Logic) now complete - ready for Week 5 (Engine & Polish)
2026-01-25 13:02:56 -06:00
Cal Corum
5e99566560 Add rules validator, win conditions checker, and coverage gap tests
- Implement rules_validator.py with config-driven action validation for all 11 action types
- Implement win_conditions.py with point/prize-based, knockout, deck-out, turn limit, and timeout checks
- Add ForcedAction model to GameState for blocking actions (e.g., select new active after KO)
- Add ActiveConfig with max_active setting for future double-battle support
- Add TrainerConfig.stadium_same_name_replace option
- Add DeckConfig.starting_hand_size option
- Rename from_energy_deck to from_energy_zone for consistency
- Fix unreachable code bug in GameState.get_opponent_id()
- Add 16 coverage gap tests for edge cases (card registry corruption, forced actions, etc.)
- 584 tests passing at 97% coverage

Completes HIGH-005, HIGH-006, TEST-009, TEST-010 from PROJECT_PLAN.json
2026-01-25 12:57:06 -06:00
Cal Corum
dba2813f80 Add effects system with configurable weakness/resistance
Effects System (Week 3):
- EffectContext: helper methods for player/card access, params, coin flips
- EffectResult: success, message, effect_type, details for logging
- @effect_handler decorator with sync/async support and introspection
- resolve_effect() for executing effects by ID

Built-in Handlers (13 total):
- deal_damage: raw damage primitive (poison, burn, recoil)
- attack_damage: combat damage with modifiers, weakness, resistance
- heal, draw_cards, discard_from_hand, shuffle_deck
- apply_status, remove_status
- coin_flip_damage, bench_damage
- discard_energy, modify_hp, modify_retreat_cost

Configurable Weakness/Resistance:
- ModifierMode enum: MULTIPLICATIVE (x2) or ADDITIVE (+20)
- CombatConfig in RulesConfig for game-wide defaults
- WeaknessResistance supports per-card mode/value overrides
- Legacy 'modifier' field maintained for backwards compatibility

Test Coverage: 98% (418 tests)
- 84 tests for effects system (base, registry, handlers)
- Comprehensive edge case coverage for all handlers
- CardDefinition helper methods tested for non-Pokemon cards
- Zone edge cases (draw_bottom empty, peek_bottom overflow)
2026-01-25 00:25:38 -06:00
Cal Corum
092f493cc8 Add stat modifiers and attack cost overrides to CardInstance
Support card effects that modify Pokemon stats:
- hp_modifier: Additive HP change (e.g., +20 from Giant Cape tool)
- retreat_cost_modifier: Additive retreat cost change (e.g., -99 for Float Stone)
- damage_modifier: Additive damage change for attacks
- attack_cost_overrides: dict[int, list[EnergyType]] for per-attack cost changes

Added helper methods:
- effective_hp(base_hp) - returns max(1, base_hp + hp_modifier)
- effective_retreat_cost(base_cost) - returns max(0, base_cost + modifier)
- effective_attack_cost(attack_index, base_cost) - returns override or base

Updated is_knocked_out() and remaining_hp() to use effective HP.

Also updated PROJECT_PLAN.json:
- Marked HIGH-003, TEST-006, HIGH-004 as completed (Week 2 complete)
- Updated test counts and notes to reflect stat modifier coverage

289 tests passing.
2026-01-24 23:52:20 -06:00
Cal Corum
325f1e8af5 Refactor turn action tracking from booleans to counters for RulesConfig support
Replace hardcoded boolean flags with integer counters to support configurable
per-turn limits from RulesConfig. This enables custom game modes with different
rules (e.g., 2 energy attachments per turn, unlimited items, etc.).

PlayerState changes:
- energy_attached_this_turn -> energy_attachments_this_turn (int)
- supporter_played_this_turn -> supporters_played_this_turn (int)
- stadium_played_this_turn -> stadiums_played_this_turn (int)
- retreated_this_turn -> retreats_this_turn (int)
- Added items_played_this_turn (int)
- Added can_play_stadium() and can_play_item() methods
- Renamed reset_turn_flags() to reset_turn_state()

Ability/CardInstance changes:
- Ability.once_per_turn (bool) -> uses_per_turn (int|None)
- CardInstance.ability_used_this_turn -> ability_uses_this_turn (int)
- Added CardInstance.can_use_ability(ability) method

All methods now properly compare counters against RulesConfig or Ability limits.
270 tests passing.
2026-01-24 23:16:37 -06:00
Cal Corum
725c8ccc5c Add GameState, PlayerState, Zone models and test fixtures
Core game state models:
- Zone: Card collection with deck operations (draw, shuffle, peek, etc.)
- PlayerState: All player zones, score, and per-turn action flags
- GameState: Complete game state with card registry, turn tracking, win conditions

Test fixtures (conftest.py):
- Sample card definitions: Pokemon (Pikachu, Raichu, Charizard, EX, V, VMAX)
- Trainer cards: Item (Potion), Supporter (Professor Oak), Stadium, Tool
- Energy cards: Basic and special energy
- Pre-configured game states: empty, mid-game, near-win scenarios
- Factory fixtures for CardInstance and SeededRandom

Tests: 55 new tests for game state models (259 total passing)

Note: GameState imported directly from game_state module to avoid
circular imports with config module.
2026-01-24 22:55:31 -06:00
Cal Corum
32541af682 Add card/action models with stage/variant separation
- Add CardDefinition and CardInstance models for card templates and in-game state
- Add Attack, Ability, and WeaknessResistance models for Pokemon card components
- Add 11 action types as discriminated union (PlayPokemon, Evolve, Attack, etc.)
- Split PokemonStage (BASIC, STAGE_1, STAGE_2) from PokemonVariant (NORMAL, EX, GX, V, VMAX, VSTAR)
- Stage determines evolution mechanics, variant determines knockout points
- Update PrizeConfig to use variant for knockout point calculation
- VSTAR and VMAX both worth 3 points; EX, GX, V worth 2 points; NORMAL worth 1 point

Tests: 204 passing, all linting clean
2026-01-24 22:35:31 -06:00
Cal Corum
3e82280efb Add game engine foundation: enums, config, and RNG modules
- Create core module structure with models and effects subdirectories
- Add enums module with CardType, EnergyType, TurnPhase, StatusCondition, etc.
- Add RulesConfig with Mantimon TCG defaults (40-card deck, 4 points to win)
- Add RandomProvider protocol with SeededRandom (testing) and SecureRandom (production)
- Include comprehensive tests for all modules (97 tests passing)

Defaults reflect GAME_RULES.md: Pokemon Pocket-style energy deck,
first turn can attack but not attach energy, 30-turn limit enabled.
2026-01-24 22:14:45 -06:00
Cal Corum
234e9a95c1 Add backend foundation with uv, Black, and pre-commit hooks
- Initialize FastAPI backend with uv package manager
- Configure Black, Ruff, pytest, mypy in pyproject.toml
- Add health check endpoint and initial test
- Create AGENTS.md with coding guidelines for AI agents
- Add pre-commit hook to enforce linting and tests
2026-01-24 00:12:33 -06:00