"""State manager for the Clue game.This module defines the state management for the Clue game, providing methods for gamelogic and state transitions."""fromtypingimportAnyfromhaive.games.clue.modelsimportClueGuessfromhaive.games.clue.stateimportClueStatefromhaive.games.framework.base.state_managerimportGameStateManager
[docs]classClueStateManager(GameStateManager[ClueState]):"""Manager for Clue game state."""
[docs]@classmethoddefinitialize(cls,**kwargs)->ClueState:"""Initialize a new Clue game. Args: **kwargs: Keyword arguments for game initialization Returns: ClueState: A new Clue game state """returnClueState.initialize(**kwargs)
[docs]@classmethoddefget_legal_moves(cls,state:ClueState)->list[ClueGuess]:"""Get all legal moves for the current state. Args: state: The current game state Returns: List of possible legal guesses """# In Clue, moves depend on player's hand and game state# This method could generate suggestions based on current knowledgereturn[]
[docs]@classmethoddefapply_move(cls,state:ClueState,move:ClueGuess)->ClueState:"""Apply a guess to the current state. Args: state: Current game state move: The guess to apply Returns: Updated game state """# Validate player's turn# Note: ClueGuess doesn't have a player attribute, so we use current_player# This assumes the move is being made by the current player# Validate turn limitiflen(state.guesses)>=state.max_turns:raiseValueError("Maximum number of turns reached")# Create a new statenew_state=state.model_copy()# Add the guessnew_state.guesses.append(move)# Determine if the guess matches the solutionif(move.suspect==new_state.solution.suspectandmove.weapon==new_state.solution.weaponandmove.room==new_state.solution.room):# Winning movenew_state.game_status=f"{move.player}_win"new_state.winner=move.playerreturnnew_state# Switch playersnew_state.current_player="player2"ifmove.player=="player1"else"player1"# Check if max turns reachediflen(new_state.guesses)>=new_state.max_turns:new_state.game_status=f"{new_state.solution.suspect}_win"new_state.winner=new_state.solution.suspectreturnnew_state
[docs]@classmethoddefcheck_game_status(cls,state:ClueState)->ClueState:"""Check and potentially update game status. Args: state: Current game state Returns: Updated game state """returnstate
[docs]@classmethoddefget_winner(cls,state:ClueState)->str|None:"""Get the winner of the game. Args: state: Current game state Returns: Winner of the game, or None if ongoing """returnstate.winner
[docs]@classmethoddefadd_analysis(cls,state:ClueState,player:str,hypothesis:dict[str,Any])->ClueState:"""Add a hypothesis to the state. Args: state: Current game state player: Player performing the analysis hypothesis: Hypothesis details Returns: Updated state with added hypothesis """new_state=state.model_copy()ifplayer=="player1":new_state.player1_hypotheses.append(hypothesis)else:new_state.player2_hypotheses.append(hypothesis)returnnew_state
[docs]@classmethoddefget_possible_solutions(cls,state:ClueState)->set[tuple[str,str,str]]:"""Get possible solutions based on the current game state. Args: state: Current game state Returns: Set of possible solutions as (suspect, weapon, room) tuples """# Start with all possible combinationsall_suspects=["Miss Scarlet","Colonel Mustard","Mrs. White","Mr. Green","Mrs. Peacock","Professor Plum",]all_weapons=["Candlestick","Knife","Lead Pipe","Revolver","Rope","Wrench",]all_rooms=["Hall","Lounge","Dining Room","Kitchen","Ballroom","Conservatory","Billiard Room","Library","Study",]# Filter out known invalid combinations based on player cards and# guessesplayer_cards=set(state.player1_cards+state.player2_cards)possible_solutions={(suspect,weapon,room)forsuspectinall_suspectsforweaponinall_weaponsforroominall_roomsif(suspectnotinplayer_cardsandweaponnotinplayer_cardsandroomnotinplayer_cards)}returnpossible_solutions