- 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
186 lines
5.5 KiB
Python
186 lines
5.5 KiB
Python
"""Enumeration types for the Mantimon TCG game engine.
|
|
|
|
This module defines all enum types used throughout the game engine. We use StrEnum
|
|
for JSON serialization compatibility - enum values serialize as strings directly.
|
|
|
|
Note on extensibility: While these enums define the standard types, the game engine
|
|
is designed to be configurable. Custom energy types or card types could be added
|
|
via configuration for free play mode.
|
|
"""
|
|
|
|
from enum import StrEnum
|
|
|
|
|
|
class CardType(StrEnum):
|
|
"""The primary type of a card.
|
|
|
|
Every card in the game belongs to exactly one of these types, which determines
|
|
how it can be played and what rules apply to it.
|
|
"""
|
|
|
|
POKEMON = "pokemon"
|
|
TRAINER = "trainer"
|
|
ENERGY = "energy"
|
|
|
|
|
|
class PokemonStage(StrEnum):
|
|
"""The evolution stage of a Pokemon card.
|
|
|
|
Determines how the Pokemon can be played:
|
|
- BASIC: Can be played directly from hand to bench
|
|
- STAGE_1: Must evolve from a Basic Pokemon
|
|
- STAGE_2: Must evolve from a Stage 1 Pokemon
|
|
|
|
Note: This is separate from PokemonVariant (EX, V, GX, etc.) which affects
|
|
knockout points but not evolution mechanics.
|
|
"""
|
|
|
|
BASIC = "basic"
|
|
STAGE_1 = "stage_1"
|
|
STAGE_2 = "stage_2"
|
|
|
|
|
|
class PokemonVariant(StrEnum):
|
|
"""Special variant classification for Pokemon cards.
|
|
|
|
Variants affect knockout points and may have special rules, but are
|
|
orthogonal to evolution stage. A card can be a "Basic EX" or "Stage 2 GX".
|
|
|
|
- NORMAL: Standard Pokemon, worth 1 knockout point
|
|
- EX: Worth 2 knockout points
|
|
- GX: Worth 2 knockout points, has GX attack (once per game)
|
|
- V: Worth 2 knockout points
|
|
- VMAX: Evolves from V variant, worth 3 knockout points
|
|
- VSTAR: Evolves from V variant, worth 3 knockout points, has VSTAR power
|
|
"""
|
|
|
|
NORMAL = "normal"
|
|
EX = "ex"
|
|
GX = "gx"
|
|
V = "v"
|
|
VMAX = "vmax"
|
|
VSTAR = "vstar"
|
|
|
|
|
|
class EnergyType(StrEnum):
|
|
"""Energy types available in the game.
|
|
|
|
Based on modern Pokemon TCG with 10 types. Colorless is special - any energy
|
|
can satisfy colorless requirements.
|
|
|
|
Note: The engine supports all types, but specific games can restrict which
|
|
types are enabled via RulesConfig.
|
|
"""
|
|
|
|
COLORLESS = "colorless"
|
|
DARKNESS = "darkness"
|
|
DRAGON = "dragon"
|
|
FIGHTING = "fighting"
|
|
FIRE = "fire"
|
|
GRASS = "grass"
|
|
LIGHTNING = "lightning"
|
|
METAL = "metal"
|
|
PSYCHIC = "psychic"
|
|
WATER = "water"
|
|
|
|
|
|
class TrainerType(StrEnum):
|
|
"""Subtypes of Trainer cards.
|
|
|
|
Each subtype has different rules for how many can be played per turn:
|
|
- ITEM: Unlimited per turn
|
|
- SUPPORTER: One per turn
|
|
- STADIUM: One per turn, stays in play
|
|
- TOOL: Attached to Pokemon, unlimited per turn
|
|
"""
|
|
|
|
ITEM = "item"
|
|
SUPPORTER = "supporter"
|
|
STADIUM = "stadium"
|
|
TOOL = "tool"
|
|
|
|
|
|
class TurnPhase(StrEnum):
|
|
"""Phases within a player's turn.
|
|
|
|
Turn structure:
|
|
1. SETUP: Initial game setup (draw starting hand, place basics, set prizes)
|
|
2. DRAW: Draw a card from deck
|
|
3. MAIN: Play cards, attach energy, evolve, use abilities, retreat
|
|
4. ATTACK: Declare and resolve an attack (optional)
|
|
5. END: Apply end-of-turn effects, check knockouts, score points
|
|
|
|
Valid transitions:
|
|
- SETUP -> DRAW (game start, first player's turn)
|
|
- DRAW -> MAIN
|
|
- MAIN -> ATTACK or END (can skip attack)
|
|
- ATTACK -> END
|
|
- END -> DRAW (next player's turn)
|
|
"""
|
|
|
|
SETUP = "setup"
|
|
DRAW = "draw"
|
|
MAIN = "main"
|
|
ATTACK = "attack"
|
|
END = "end"
|
|
|
|
|
|
class StatusCondition(StrEnum):
|
|
"""Status conditions that can affect Pokemon in play.
|
|
|
|
Status conditions have specific effects and removal conditions:
|
|
- POISONED: 10 damage between turns; removed by evolution, retreat, or card effect
|
|
- BURNED: 20 damage between turns + flip to remove; removed on heads
|
|
- ASLEEP: Cannot attack or retreat; removed on heads flip; overrides PARALYZED/CONFUSED
|
|
- PARALYZED: Cannot attack or retreat for 1 turn; removed at end of next turn;
|
|
overrides ASLEEP/CONFUSED
|
|
- CONFUSED: Flip to attack, 30 self-damage on tails; removed by evolution/retreat;
|
|
overrides ASLEEP/PARALYZED
|
|
|
|
Note: POISONED and BURNED stack with other conditions. ASLEEP, PARALYZED, and
|
|
CONFUSED override each other (only one can be active at a time).
|
|
"""
|
|
|
|
POISONED = "poisoned"
|
|
BURNED = "burned"
|
|
ASLEEP = "asleep"
|
|
PARALYZED = "paralyzed"
|
|
CONFUSED = "confused"
|
|
|
|
|
|
class ActionType(StrEnum):
|
|
"""Types of actions a player can take during their turn.
|
|
|
|
Each action type has specific validation rules and can only be performed
|
|
during certain phases. See rules_validator.py for details.
|
|
"""
|
|
|
|
PLAY_POKEMON = "play_pokemon"
|
|
EVOLVE = "evolve"
|
|
ATTACH_ENERGY = "attach_energy"
|
|
PLAY_TRAINER = "play_trainer"
|
|
USE_ABILITY = "use_ability"
|
|
ATTACK = "attack"
|
|
RETREAT = "retreat"
|
|
PASS = "pass"
|
|
|
|
|
|
class GameEndReason(StrEnum):
|
|
"""Reasons why a game ended.
|
|
|
|
Used in GameState.end_reason to indicate how the game concluded:
|
|
- PRIZES_TAKEN: A player took all required prize points
|
|
- NO_POKEMON: A player has no Pokemon in play (active or bench)
|
|
- DECK_EMPTY: A player cannot draw a card at the start of their turn
|
|
- RESIGNATION: A player resigned from the match
|
|
- TIMEOUT: A player ran out of time (multiplayer only)
|
|
- DRAW: The game ended in a draw (tie on points at timer expiration)
|
|
"""
|
|
|
|
PRIZES_TAKEN = "prizes_taken"
|
|
NO_POKEMON = "no_pokemon"
|
|
DECK_EMPTY = "deck_empty"
|
|
RESIGNATION = "resignation"
|
|
TIMEOUT = "timeout"
|
|
DRAW = "draw"
|