# src/haive/agents/agent_games/connect4/models.py"""Connect4 game models module.This module provides data models for the Connect4 game implementation, including: - Move validation and representation - Player decisions and analysis - Game state components - Structured output models for LLMsExample: >>> from haive.games.connect4.models import Connect4Move >>> >>> # Create and validate a move >>> move = Connect4Move( ... column=3, ... explanation="Control the center column" ... )"""# Standard library imports# Third-party importsfrompydanticimportBaseModel,Field,field_validator
[docs]classConnect4Move(BaseModel):"""Model for Connect4 moves with validation. This class represents a Connect4 move with: - Column number (0-6) - Optional explanation - Move validation Attributes: column (int): Column number (0-6). explanation (Optional[str]): Explanation of the move's purpose. Example: >>> move = Connect4Move( ... column=3, ... explanation="Control the center column" ... ) """column:int=Field(...,description="Column number (0-6) where the piece will be dropped.")explanation:str|None=Field(default=None,description="Optional explanation of the move's purpose.")
[docs]@field_validator("column")@classmethoddefvalidate_column(cls,v:int)->int:"""Validate the column number. Args: v (int): Column number to validate. Returns: int: Validated column number. Raises: ValueError: If the column number is not between 0 and 6. """ifnotisinstance(v,int)orv<0orv>6:raiseValueError("Column must be an integer between 0 and 6")returnv
def__str__(self)->str:"""String representation of the move. Returns: str: Human-readable move description. """returnf"Drop in column {self.column}"
[docs]classConnect4PlayerDecision(BaseModel):"""Model for Connect4 player decisions. This class represents a player's decision-making process: - Move selection - Position evaluation - Alternative moves considered - Reasoning process Attributes: move (Connect4Move): Chosen move with explanation. position_eval (str): Player's assessment of the position. alternatives (List[Connect4Move]): Alternative moves considered. reasoning (str): Detailed reasoning for the move choice. Example: >>> decision = Connect4PlayerDecision( ... move=Connect4Move(column=3, explanation="Control center"), ... position_eval="Strong position with center control", ... alternatives=[ ... Connect4Move(column=2, explanation="Alternative center approach") ... ], ... reasoning="Playing in column 3 maintains center control" ... ) """move:Connect4Move=Field(...,description="Selected move with explanation.")position_eval:str=Field(...,description="Player's assessment of the current position.")alternatives:list[Connect4Move]=Field(default_factory=list,description="Alternative moves that were considered.")reasoning:str=Field(...,description="Detailed reasoning for the move choice.")
[docs]classConnect4Analysis(BaseModel):"""Model for Connect4 position analysis. This class represents a detailed analysis of a Connect4 position: - Position evaluation - Center control assessment - Threat detection - Strategic plans Attributes: position_score (float): Position evaluation (-1.0 to 1.0). center_control (int): Center control rating (0-10). threats (Dict[str, List[int]]): Detected threats and opportunities. suggested_columns (List[int]): Recommended columns to play. winning_chances (int): Estimated winning chances (0-100). Example: >>> analysis = Connect4Analysis( ... position_score=0.5, ... center_control=8, ... threats={ ... "winning_moves": [3], ... "blocking_moves": [4] ... }, ... suggested_columns=[3, 2, 4], ... winning_chances=75 ... ) """@staticmethoddef_default_threats()->dict[str,list[int]]:"""Create default threats dictionary. Returns: dict[str, list[int]]: Dictionary with empty lists for winning and blocking moves. """return{"winning_moves":[],"blocking_moves":[]}position_score:float=Field(default=0.0,description="Position evaluation (-1.0 to 1.0, positive favors current player).",)center_control:int=Field(default=5,description="Rating of center column control (0-10).")threats:dict[str,list[int]]=Field(default_factory=_default_threats,description="Detected threats and opportunities.",)suggested_columns:list[int]=Field(default_factory=list,description="List of recommended columns to play.")winning_chances:int=Field(default=50,description="Estimated winning chances (0-100).")
[docs]@field_validator("center_control")@classmethoddefvalidate_center_control(cls,v:int)->int:"""Validate the center control rating. Args: v (int): Center control rating to validate. Returns: int: Validated center control rating. Raises: ValueError: If the rating is not between 0 and 10. """ifnotisinstance(v,int)orv<0orv>10:raiseValueError("Center control must be an integer between 0 and 10")returnv
[docs]@field_validator("winning_chances")@classmethoddefvalidate_winning_chances(cls,v:int)->int:"""Validate the winning chances percentage. Args: v (int): Winning chances percentage to validate. Returns: int: Validated winning chances percentage. Raises: ValueError: If the percentage is not between 0 and 100. """ifnotisinstance(v,int)orv<0orv>100:raiseValueError("Winning chances must be an integer between 0 and 100")returnv