Changed ability_uses_this_turn from int to dict[int, int] to track each
ability's usage independently:
- ability_uses_this_turn: dict[int, int] maps ability index to use count
- can_use_ability() now requires ability_index parameter
- Added get_ability_uses() and increment_ability_uses() helper methods
- reset_turn_state() clears the dict instead of setting to 0
This fixes the bug where using one ability could incorrectly block
another ability on the same Pokemon from being used.
789 tests passing.
Major refactor to properly track attached cards and evolution history:
Model Changes (app/core/models/card.py):
- Change attached_energy from list[str] to list[CardInstance]
- Change attached_tools from list[str] to list[CardInstance]
- Add cards_underneath field for evolution stack tracking
- Update attach_energy/detach_energy to work with CardInstance
- Add attach_tool/detach_tool methods
- Add get_all_attached_cards helper
Engine Changes (app/core/engine.py):
- _execute_attach_energy: Pass full CardInstance to attach_energy
- _execute_evolve: Build evolution stack, transfer attachments, clear status
- _execute_retreat: Detached energy goes to discard pile
- Fix: Evolution now clears status conditions (Pokemon TCG standard)
Game State (app/core/models/game_state.py):
- find_card_instance now searches attached_energy, attached_tools, cards_underneath
Turn Manager (app/core/turn_manager.py):
- process_knockout: Discard all attached energy, tools, and evolution stack
Effects (app/core/effects/handlers.py):
- discard_energy: Find owner's discard pile and move detached energy there
- NEW devolve effect: Remove evolution stages with configurable destination
- Fix: Use EffectType.SPECIAL instead of non-existent EffectType.ZONE
Rules Validator (app/core/rules_validator.py):
- Update energy type checking to iterate CardInstance objects
Tests:
- Update existing tests for new CardInstance-based energy attachment
- NEW test_evolution_stack.py with 28 comprehensive tests covering:
- Evolution stack building (Basic -> Stage 1 -> Stage 2)
- Energy/tool transfer and damage carryover on evolution
- Devolve effect (single/multi stage, hand/discard destination, KO check)
- Knockout processing with all attachments going to discard
- find_card_instance for attached cards and evolution stack
All 765 tests pass.
- 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