games.tic_tac_toe.state¶
Comprehensive state management system for strategic Tic Tac Toe gameplay.
from typing import Any This module provides sophisticated state management for Tic Tac Toe games with complete support for game mechanics, strategic analysis, and LangGraph integration. The state system maintains game rules, move validation, and comprehensive game history for educational and competitive gameplay.
The state system supports: - Complete 3x3 board representation with move validation - Turn-based gameplay with X and O player management - Move history tracking for game replay and analysis - Strategic analysis integration for both players - Win condition detection (rows, columns, diagonals) - Draw detection and game status management - LangGraph reducers for concurrent state updates - Error handling and recovery mechanisms
Examples
Initializing a new game:
state = TicTacToeState.initialize(
first_player="X",
player_X="player1",
player_O="player2"
)
Making a move and checking status:
# Make a center move
state.board[1][1] = "X"
state.move_history.append(
TicTacToeMove(row=1, col=1, player="X")
)
# Check game state
if state.is_board_full:
state.game_status = "draw"
Analyzing board positions:
empty_cells = state.empty_cells
print(f"Available moves: {empty_cells}")
# Pretty print the board
print(state.board_string)
Managing player turns:
current = state.current_player_name
if state.turn == "X":
state.turn = "O"
else:
state.turn = "X"
Note
All state updates should use LangGraph Commands to ensure proper reducer behavior and concurrent update handling.
Classes¶
Comprehensive state model for Tic Tac Toe gameplay with LangGraph integration. |
Functions¶
|
Reducer for message-like lists that should be concatenated. |
|
Special reducer for the board that always replaces with the new board. |
|
Reducer that always takes the new value (right side). |
Module Contents¶
- class games.tic_tac_toe.state.TicTacToeState(/, **data)¶
Bases:
haive.games.framework.base.state.GameState
Comprehensive state model for Tic Tac Toe gameplay with LangGraph integration.
This class provides complete state management for Tic Tac Toe games, supporting both traditional gameplay mechanics and advanced features for AI analysis. The state system maintains game rules, validates moves, tracks history, and integrates with LangGraph for distributed gameplay and concurrent updates.
The state model supports: - 3x3 board representation with None/X/O values - Turn management with alternating X and O players - Move history for game replay and analysis - Player-specific analysis storage - Win/draw detection and game status tracking - Error handling for invalid moves - LangGraph reducers for proper state updates - Pretty-printing for board visualization
All fields use explicit reducers to ensure proper behavior with LangGraph’s concurrent update system, preventing state corruption during parallel operations.
- Parameters:
data (Any)
- turn¶
Current player’s turn with replace reducer.
- Type:
Literal[“X”, “O”]
- game_status¶
Game state (ongoing/X_win/O_win/draw) with replace reducer.
- Type:
Literal
- move_history¶
Complete move history with accumulating reducer.
- Type:
List[TicTacToeMove]
- player_X¶
Player using X symbol with replace reducer.
- Type:
Literal
- player_O¶
Player using O symbol with replace reducer.
- Type:
Literal
- player1_analysis¶
Player 1’s analyses with accumulating reducer.
- Type:
List[TicTacToeAnalysis]
- player2_analysis¶
Player 2’s analyses with accumulating reducer.
- Type:
List[TicTacToeAnalysis]
Examples
Creating and initializing a game:
state = TicTacToeState.initialize( first_player="X", player_X="Alice", player_O="Bob" ) assert state.turn == "X" assert state.game_status == "ongoing" assert all(cell is None for row in state.board for cell in row)
Making moves and updating state:
# X plays center state.board[1][1] = "X" state.move_history.append( TicTacToeMove(row=1, col=1, player="X") ) state.turn = "O" # O plays corner state.board[0][0] = "O" state.move_history.append( TicTacToeMove(row=0, col=0, player="O") ) state.turn = "X"
Checking win conditions:
# X wins with diagonal state.board = [ ["X", "O", None], ["O", "X", None], [None, None, "X"] ] state.game_status = "X_win" state.winner = "player1"
Board visualization:
print(state.board_string) # Output: # 0 1 2 # ------- # 0 |X|O| | # ------- # 1 |O|X| | # ------- # 2 | | |X| # -------
Note
State updates should be performed through LangGraph Commands to ensure proper reducer behavior and prevent concurrent update conflicts.
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 initialize(**kwargs)¶
Initialize a new Tic Tac Toe game with optional configuration.
Factory method to create a properly initialized game state with all required fields set to appropriate starting values.
- Parameters:
**kwargs – Optional configuration parameters: first_player (Literal[“X”, “O”]): Which player goes first (default: “X”). player_X (Literal[“player1”, “player2”]): Player using X (default: “player1”). player_O (Literal[“player1”, “player2”]): Player using O (default: “player2”).
- Returns:
Newly initialized game state ready for play.
- Return type:
Examples
Default initialization:
state = TicTacToeState.initialize() assert state.turn == "X" assert state.player_X == "player1" assert state.player_O == "player2"
Custom player assignment:
state = TicTacToeState.initialize( first_player="O", player_X="player2", player_O="player1" ) assert state.turn == "O" assert state.current_player_name == "player1"
Tournament setup:
state = TicTacToeState.initialize( first_player="X", player_X="player1", player_O="player2" ) # Ready for competitive play
- classmethod validate_board(board)¶
Validate that the board is a proper 3x3 grid with valid symbols.
Ensures the board maintains the correct structure and contains only valid values (None for empty, ‘X’, or ‘O’ for occupied cells).
- Parameters:
board (List[List[Optional[str]]]) – The board to validate.
- Returns:
Validated board or default empty board.
- Return type:
List[List[Optional[str]]]
- Raises:
ValueError – If the board structure is invalid or contains invalid values.
Examples
Valid board:
board = [["X", None, "O"], [None, "X", None], ["O", None, "X"]] # Passes validation
Invalid board (wrong size):
board = [["X", "O"], ["O", "X"]] # 2x2 instead of 3x3 # Raises ValueError: "Board must have 3 rows"
Invalid board (invalid symbol):
board = [["X", "Y", "O"], [None, None, None], [None, None, None]] # Raises ValueError: "Cell values must be None, 'X', or 'O', got Y"
- property board_string: str¶
Get a pretty-printed string representation of the board.
Creates a human-readable ASCII representation of the current board state with row and column indices for easy reference.
- Returns:
Multiline string representing the current board state.
- Return type:
Examples
Empty board:
0 1 2 ------- 0 | | | | ------- 1 | | | | ------- 2 | | | | -------
Game in progress:
0 1 2 ------- 0 |X|O| | ------- 1 | |X| | ------- 2 |O| |X| -------
- property current_player_name: str¶
Get the identifier of the player whose turn it is.
Maps the current turn symbol (X or O) to the assigned player identifier.
- Returns:
The player identifier (“player1” or “player2”).
- Return type:
Examples
>>> state = TicTacToeState.initialize() >>> state.turn = "X" >>> state.current_player_name 'player1'
>>> state.turn = "O" >>> state.current_player_name 'player2'
- property empty_cells: list[tuple[int, int]]¶
Return a list of coordinates for all empty cells on the board.
Useful for determining available moves and checking if the game can continue.
Examples
>>> state = TicTacToeState.initialize() >>> state.empty_cells [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
>>> state.board[1][1] = "X" >>> len(state.empty_cells) 8
- property is_board_full: bool¶
Check whether the board is completely filled with no empty cells.
Used to detect draw conditions when no player has won.
- Returns:
True if all cells are occupied, False otherwise.
- Return type:
Examples
>>> state = TicTacToeState.initialize() >>> state.is_board_full False
>>> # Fill the board >>> state.board = [["X", "O", "X"], ["O", "X", "O"], ["O", "X", "X"]] >>> state.is_board_full True
- games.tic_tac_toe.state.add_messages_reducer(left, right)¶
Reducer for message-like lists that should be concatenated.
This reducer is used for accumulating lists like move history and analysis results, preserving all historical data.
- Parameters:
- Returns:
Concatenated list with all items.
- Return type:
Examples
>>> add_messages_reducer([1, 2], [3, 4]) [1, 2, 3, 4] >>> add_messages_reducer([], [1, 2]) [1, 2]
- games.tic_tac_toe.state.replace_board_reducer(left, right)¶
Special reducer for the board that always replaces with the new board.
This ensures the board state is always consistent and prevents partial updates that could create invalid game states.
- Parameters:
left (Any) – Existing board state.
right (Any) – New board state.
- Returns:
The new board state.
- Return type:
Any
- games.tic_tac_toe.state.replace_reducer(left, right)¶
Reducer that always takes the new value (right side).
This reducer is used for fields that should be completely replaced on update rather than merged or concatenated.
- Parameters:
left (Any) – Existing value in the state.
right (Any) – New value to replace with.
- Returns:
The new value (right side).
- Return type:
Any
Examples
>>> replace_reducer("X", "O") 'O' >>> replace_reducer([1, 2], [3, 4]) [3, 4]