haive.games.risk.models¶

Pydantic models for Risk game components.

This module defines comprehensive data models for the Risk strategy game, including territories, continents, players, cards, moves, and game analysis. All models use Pydantic for validation with extensive documentation and examples.

The Risk implementation supports classic world domination gameplay with AI-powered strategic analysis, multi-phase turns, and complex territorial control mechanics.

Examples

Creating a territory:

territory = Territory(
    name="Eastern Australia",
    continent="Australia",
    owner="player_1",
    armies=5,
    adjacent=["Western Australia", "New Guinea"]
)

Setting up a player:

player = Player(
    name="General Smith",
    cards=[Card(card_type=CardType.INFANTRY, territory_name="Alaska")],
    unplaced_armies=3
)

Creating an attack move:

attack = RiskMove(
    move_type=MoveType.ATTACK,
    player="player_1",
    from_territory="Ukraine",
    to_territory="Middle East",
    attack_dice=3
)

Classes¶

Card

A Risk card that can be traded for army reinforcements.

CardType

Types of Risk cards for army reinforcement trading.

Continent

A continent grouping of territories with bonus reinforcements.

GameStatus

Overall status of the Risk game.

MoveType

Types of moves available in Risk gameplay.

PhaseType

Game phases in Risk turn structure.

Player

A player in the Risk game.

RiskAnalysis

Comprehensive analysis of a player's Risk position.

RiskMove

A move action in the Risk game.

Territory

A territory on the Risk game board.

Module Contents¶

class haive.games.risk.models.Card(/, **data)[source]¶

Bases: pydantic.BaseModel

A Risk card that can be traded for army reinforcements.

Risk cards are earned by conquering at least one territory per turn and can be accumulated and traded in strategic sets for additional armies. Each card typically shows a territory and has a unit type.

The card system adds strategic depth by encouraging aggressive play (to earn cards) while providing timing decisions about when to trade for maximum advantage.

Parameters:

data (Any)

card_type¶

The military unit type shown on the card.

Type:

CardType

territory_name¶

Territory depicted on the card, if any.

Type:

Optional[str]

Examples

Territory-specific card:

alaska_card = Card(
    card_type=CardType.INFANTRY,
    territory_name="Alaska"
)

Generic unit card:

cavalry_card = Card(
    card_type=CardType.CAVALRY
    # No specific territory
)

Wild card:

wild_card = Card(
    card_type=CardType.WILD,
    territory_name="Special"
)

Note

Territory names on cards are typically for thematic purposes and don’t affect trading value, but may provide strategic information about board state.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

property is_wild: bool¶

Check if this is a wild card.

Returns:

True if this is a wild card that can substitute for any type.

Return type:

bool

Examples

>>> wild_card = Card(card_type=CardType.WILD)
>>> wild_card.is_wild
True
>>> infantry_card = Card(card_type=CardType.INFANTRY)
>>> infantry_card.is_wild
False
class haive.games.risk.models.CardType[source]¶

Bases: str, enum.Enum

Types of Risk cards for army reinforcement trading.

Risk cards are collected by conquering territories and can be traded in sets for additional armies. The four card types correspond to different military units and provide strategic options for players.

INFANTRY¶

Basic ground unit card, most common type.

CAVALRY¶

Mobile unit card, medium rarity.

ARTILLERY¶

Heavy weapon card, provides firepower bonus.

WILD¶

Special card that can substitute for any other type.

Examples

Standard card types:

infantry_card = CardType.INFANTRY
cavalry_card = CardType.CAVALRY
artillery_card = CardType.ARTILLERY

Special wild card:

wild_card = CardType.WILD  # Can be used as any type

Trading combinations:

# Valid trading sets:
# - 3 of same type (3 infantry, 3 cavalry, 3 artillery)
# - 1 of each type (1 infantry, 1 cavalry, 1 artillery)
# - Any combination with wild cards

Note

Card trading values typically increase each time cards are traded, starting at 4 armies for the first trade and increasing by 2 each time.

Initialize self. See help(type(self)) for accurate signature.

class haive.games.risk.models.Continent(/, **data)[source]¶

Bases: pydantic.BaseModel

A continent grouping of territories with bonus reinforcements.

Continents provide structure to the Risk board and offer strategic objectives. Players who control all territories in a continent receive bonus armies each turn, creating natural strategic goals.

Continental control is often the key to victory in Risk, as the bonus armies compound over time and provide significant advantages in the lengthy conquest campaigns.

Parameters:

data (Any)

name¶

The name of the continent.

Type:

str

bonus¶

Bonus armies awarded for complete continental control.

Type:

int

territories¶

Names of all territories in this continent.

Type:

List[str]

Examples

High-value continent:

asia = Continent(
    name="Asia",
    bonus=7,  # Highest bonus but hardest to hold
    territories=[
        "Ural", "Siberia", "Yakutsk", "Kamchatka", "Irkutsk",
        "Mongolia", "China", "Siam", "India", "Middle East",
        "Afghanistan", "Japan"
    ]
)

Balanced continent:

europe = Continent(
    name="Europe",
    bonus=5,
    territories=[
        "Iceland", "Scandinavia", "Ukraine", "Great Britain",
        "Northern Europe", "Western Europe", "Southern Europe"
    ]
)

Easy-to-defend continent:

australia = Continent(
    name="Australia",
    bonus=2,  # Small but defensible
    territories=["Indonesia", "New Guinea", "Western Australia", "Eastern Australia"]
)

Note

Continent bonuses create risk-reward tradeoffs. Larger continents offer bigger bonuses but are harder to conquer and defend. Australia is traditionally the easiest to defend but offers the smallest bonus.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

classmethod validate_territories(v)[source]¶

Validate territory list is not empty and contains valid names.

Parameters:

v (List[str]) – Territory names to validate.

Returns:

Validated territory list.

Return type:

List[str]

Raises:

ValueError – If territory list is empty or contains invalid names.

property bonus_per_territory: float¶

Calculate bonus armies per territory in this continent.

Returns:

Bonus efficiency ratio for strategic evaluation.

Return type:

float

Note

Higher ratios indicate more efficient continents to control. Australia typically has the highest ratio (0.5), while Asia has a lower ratio (0.58) despite its large bonus.

property territory_count: int¶

Get the number of territories in this continent.

Returns:

Count of territories in the continent.

Return type:

int

class haive.games.risk.models.GameStatus[source]¶

Bases: str, enum.Enum

Overall status of the Risk game.

Tracks the high-level state of the game to determine whether play should continue or if victory conditions have been met.

IN_PROGRESS¶

Game is actively being played.

FINISHED¶

Game has ended with a clear victory.

Examples

Active game:

status = GameStatus.IN_PROGRESS
# Players continue taking turns

Completed game:

status = GameStatus.FINISHED
# Victory conditions met, declare winner

Initialize self. See help(type(self)) for accurate signature.

class haive.games.risk.models.MoveType[source]¶

Bases: str, enum.Enum

Types of moves available in Risk gameplay.

Risk turns are structured around specific move types that correspond to different phases of play. Each move type has distinct rules, timing requirements, and strategic implications.

The move type system ensures proper game flow and enables the AI to understand and plan appropriate actions for each phase.

PLACE_ARMIES¶

Deploy reinforcement armies to controlled territories.

ATTACK¶

Launch military attacks against adjacent enemy territories.

FORTIFY¶

Transfer armies between connected friendly territories.

TRADE_CARDS¶

Exchange card sets for additional armies.

Examples

Turn phase progression:

# 1. Start of turn - reinforcement phase
trade_move = MoveType.TRADE_CARDS  # If required/desired
place_move = MoveType.PLACE_ARMIES

# 2. Combat phase
attack_moves = [MoveType.ATTACK, MoveType.ATTACK, ...]

# 3. End of turn - reorganization
fortify_move = MoveType.FORTIFY  # Optional

Strategic move sequencing:

# Aggressive expansion turn
moves = [
    MoveType.PLACE_ARMIES,  # Strengthen attack position
    MoveType.ATTACK,        # Primary assault
    MoveType.ATTACK,        # Follow-up attack
    MoveType.FORTIFY        # Consolidate gains
]

Note

Move types correspond to Risk’s traditional turn structure: reinforcement → attack → fortification. Card trading can occur at the start if the player has 3+ cards.

Initialize self. See help(type(self)) for accurate signature.

class haive.games.risk.models.PhaseType[source]¶

Bases: str, enum.Enum

Game phases in Risk turn structure.

Risk gameplay follows a structured turn sequence with distinct phases that determine available actions and strategic timing. Understanding phase transitions is crucial for AI planning and move validation.

The phase system provides clear game flow while allowing for strategic flexibility within each phase’s constraints.

SETUP¶

Initial game setup with territory allocation and army placement.

REINFORCE¶

Army reinforcement and card trading phase.

ATTACK¶

Combat phase with territorial conquest attempts.

FORTIFY¶

End-of-turn army repositioning and consolidation.

GAME_OVER¶

Game completion with victory conditions met.

Examples

Standard turn progression:

turn_phases = [
    PhaseType.REINFORCE,  # Get armies, place them
    PhaseType.ATTACK,     # Optional combat
    PhaseType.FORTIFY     # Optional repositioning
]

Game lifecycle:

game_phases = [
    PhaseType.SETUP,      # Initial setup
    # ... many turns of REINFORCE → ATTACK → FORTIFY
    PhaseType.GAME_OVER   # Victory achieved
]

Note

Phase enforcement ensures proper Risk rule compliance and provides structure for AI decision-making algorithms.

Initialize self. See help(type(self)) for accurate signature.

class haive.games.risk.models.Player(/, **data)[source]¶

Bases: pydantic.BaseModel

A player in the Risk game.

Players are the strategic decision-makers in Risk, controlling territories, managing armies, and executing complex multi-turn plans for world domination. Each player maintains their own hand of cards and army reserves.

Player management includes tracking eliminated status, which occurs when a player loses all territories, transferring their cards to the conquering player and removing them from play.

Parameters:

data (Any)

name¶

The player’s identifier and display name.

Type:

str

cards¶

Risk cards in the player’s hand for trading.

Type:

List[Card]

unplaced_armies¶

Armies available for placement but not yet deployed.

Type:

int

eliminated¶

Whether this player has been defeated.

Type:

bool

Examples

Active player with resources:

player = Player(
    name="General Patton",
    cards=[
        Card(card_type=CardType.INFANTRY, territory_name="Alaska"),
        Card(card_type=CardType.CAVALRY, territory_name="Brazil"),
        Card(card_type=CardType.ARTILLERY, territory_name="Egypt")
    ],
    unplaced_armies=5
)

Starting player:

new_player = Player(
    name="Commander Lee",
    unplaced_armies=20  # Initial army allocation
)

Eliminated player:

defeated_player = Player(
    name="Admiral Nelson",
    eliminated=True
    # Cards transferred to conquering player
)

Note

Card accumulation is crucial for late-game army generation. Players must balance aggressive expansion (to earn cards) with defensive positioning (to avoid elimination).

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

classmethod validate_unplaced_armies(v)[source]¶

Validate unplaced army count is reasonable.

Parameters:

v (int) – Unplaced army count to validate.

Returns:

Validated army count.

Return type:

int

Raises:

ValueError – If army count is negative.

property can_trade_cards: bool¶

Check if player has enough cards to make a trade.

Returns:

True if player has 3+ cards (minimum for trading).

Return type:

bool

Note

Players with 5+ cards must trade at the start of their turn. Trading with exactly 3 cards is optional but often strategic.

property must_trade_cards: bool¶

Check if player is forced to trade cards.

Returns:

True if player has 5+ cards and must trade before placing armies.

Return type:

bool

Note

This rule prevents card hoarding and maintains game flow.

class haive.games.risk.models.RiskAnalysis(/, **data)[source]¶

Bases: pydantic.BaseModel

Comprehensive analysis of a player’s Risk position.

Strategic analysis is crucial for AI decision-making in Risk’s complex, multi-turn gameplay. This model provides structured evaluation of territorial control, military strength, and strategic positioning.

The analysis system enables sophisticated AI that can evaluate long-term strategic positions beyond immediate tactical moves, considering continental bonuses, defensive positioning, and overall game progression.

Parameters:

data (Any)

player¶

The player being analyzed.

Type:

str

controlled_continents¶

Continents fully controlled by the player.

Type:

List[str]

controlled_territories¶

Total number of territories owned.

Type:

int

total_armies¶

Sum of all armies across all territories.

Type:

int

position_evaluation¶

Overall strategic assessment.

Type:

str

recommended_move¶

Suggested optimal move.

Type:

RiskMove

explanation¶

Detailed reasoning for the analysis and recommendation.

Type:

str

Examples

Strong position analysis:

analysis = RiskAnalysis(
    player="player_1",
    controlled_continents=["Australia", "South America"],
    controlled_territories=18,
    total_armies=45,
    position_evaluation="winning",
    recommended_move=RiskMove(
        move_type=MoveType.ATTACK,
        player="player_1",
        from_territory="Brazil",
        to_territory="North Africa",
        attack_dice=3
    ),
    explanation="Player controls two continents providing 5 bonus armies per turn. Should continue aggressive expansion into Africa while maintaining defensive positions."
)

Defensive position analysis:

analysis = RiskAnalysis(
    player="player_2",
    controlled_continents=[],
    controlled_territories=8,
    total_armies=12,
    position_evaluation="losing",
    recommended_move=RiskMove(
        move_type=MoveType.FORTIFY,
        player="player_2",
        from_territory="Greenland",
        to_territory="Quebec",
        armies=3
    ),
    explanation="Player is behind in territory count and lacks continental bonuses. Should consolidate forces and defend key chokepoints to survive."
)

Note

Analysis quality directly impacts AI performance. Sophisticated evaluation considers not just current position but also trajectory, opponent threats, and multi-turn strategic opportunities.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

classmethod validate_position_evaluation(v)[source]¶

Validate position evaluation uses standard terminology.

Parameters:

v (str) – Position evaluation to validate.

Returns:

Validated evaluation string.

Return type:

str

Raises:

ValueError – If evaluation is not recognized.

property average_armies_per_territory: float¶

Calculate average army strength per territory.

Returns:

Average armies per territory for strategic assessment.

Return type:

float

Note

Higher ratios indicate stronger defensive positions or preparation for major offensives.

property continent_bonus: int¶

Calculate total bonus armies from controlled continents.

Returns:

Total bonus armies per turn from continental control.

Return type:

int

Note

This is a simplified calculation. Real implementation would need access to continent definitions with their bonus values.

class haive.games.risk.models.RiskMove(/, **data)[source]¶

Bases: pydantic.BaseModel

A move action in the Risk game.

Risk moves represent all player actions during gameplay, from army placement and attacks to strategic repositioning. Each move contains all necessary information for validation and execution.

The flexible move structure accommodates Risk’s varied action types while providing clear validation rules and strategic context for AI decision-making systems.

Parameters:

data (Any)

move_type¶

The category of action being performed.

Type:

MoveType

player¶

The player executing this move.

Type:

str

from_territory¶

Source territory for attacks and fortifications.

Type:

Optional[str]

to_territory¶

Target territory for all move types.

Type:

Optional[str]

armies¶

Number of armies to deploy, attack with, or transfer.

Type:

Optional[int]

cards¶

Cards to trade for army bonuses.

Type:

Optional[List[Card]]

attack_dice¶

Number of dice to use in attack (1-3).

Type:

Optional[int]

Examples

Army placement move:

place_move = RiskMove(
    move_type=MoveType.PLACE_ARMIES,
    player="player_1",
    to_territory="Ukraine",
    armies=5
)

Attack move:

attack_move = RiskMove(
    move_type=MoveType.ATTACK,
    player="player_1",
    from_territory="Ukraine",
    to_territory="Middle East",
    armies=6,  # Attacking with 6 armies (max 3 dice)
    attack_dice=3
)

Fortification move:

fortify_move = RiskMove(
    move_type=MoveType.FORTIFY,
    player="player_1",
    from_territory="Siberia",
    to_territory="China",
    armies=4
)

Card trading move:

trade_move = RiskMove(
    move_type=MoveType.TRADE_CARDS,
    player="player_1",
    cards=[
        Card(card_type=CardType.INFANTRY),
        Card(card_type=CardType.CAVALRY),
        Card(card_type=CardType.ARTILLERY)
    ]
)

Note

Move validation depends on game state, including territory ownership, army counts, and adjacency relationships. Invalid moves should be rejected with clear error messages.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

classmethod validate_armies(v)[source]¶

Validate army count is positive if provided.

Parameters:

v (Optional[int]) – Army count to validate.

Returns:

Validated army count or None.

Return type:

Optional[int]

Raises:

ValueError – If army count is not positive.

classmethod validate_attack_dice(v)[source]¶

Validate attack dice count is within valid range.

Parameters:

v (Optional[int]) – Dice count to validate.

Returns:

Validated dice count or None.

Return type:

Optional[int]

Raises:

ValueError – If dice count is not 1-3.

property is_aggressive: bool¶

Determine if this move is aggressive (attack or large army placement).

Returns:

True if move represents aggressive action.

Return type:

bool

Note

Used for AI personality and strategic analysis.

class haive.games.risk.models.Territory(/, **data)[source]¶

Bases: pydantic.BaseModel

A territory on the Risk game board.

Territories are the fundamental units of control in Risk. Each territory belongs to a continent, can be owned by a player, contains armies for defense, and connects to adjacent territories for movement and attack.

The territorial system forms the core of Risk strategy, as players must control territories to earn reinforcements and achieve victory conditions (total world domination or objective completion).

Parameters:

data (Any)

name¶

Unique identifier and display name for the territory.

Type:

str

continent¶

The continent this territory belongs to.

Type:

str

owner¶

The player who currently controls this territory.

Type:

Optional[str]

armies¶

Number of armies stationed in this territory for defense.

Type:

int

adjacent¶

Names of territories that border this one.

Type:

List[str]

Examples

Strategic territory setup:

ukraine = Territory(
    name="Ukraine",
    continent="Europe",
    owner="player_1",
    armies=8,
    adjacent=["Scandinavia", "Northern Europe", "Southern Europe",
             "Ural", "Afghanistan", "Middle East"]
)

Neutral territory:

greenland = Territory(
    name="Greenland",
    continent="North America",
    # No owner initially
    armies=2,
    adjacent=["Northwest Territory", "Ontario", "Quebec", "Iceland"]
)

Fortified position:

egypt = Territory(
    name="Egypt",
    continent="Africa",
    owner="player_2",
    armies=12,  # Heavily fortified
    adjacent=["Libya", "East Africa", "Middle East"]
)

Note

Territory adjacency defines the game’s strategic geography. Control of key chokepoints and continental borders often determines game outcomes.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

classmethod validate_armies(v)[source]¶

Validate army count is reasonable.

Parameters:

v (int) – Army count to validate.

Returns:

Validated army count.

Return type:

int

Raises:

ValueError – If army count is negative.

classmethod validate_name(v)[source]¶

Validate territory name is properly formatted.

Parameters:

v (str) – Territory name to validate.

Returns:

Cleaned and validated territory name.

Return type:

str

Raises:

ValueError – If name is empty or contains invalid characters.

property defense_strength: int¶

Calculate defensive strength of this territory.

Returns:

Maximum dice this territory can roll in defense (1-2).

Return type:

int

Note

Territories with 1 army can defend with 1 die, territories with 2+ armies can defend with 2 dice.

property is_occupied: bool¶

Check if territory is currently occupied by a player.

Returns:

True if territory has an owner, False if neutral.

Return type:

bool