engine package

Submodules

engine.cell module

class engine.cell.Cell(played_by=<Player.NONE: 0>)[source]

Bases: object

A cell in a game of TicTacToe

This class records the Player

is_played() → bool[source]

Whether this cell has been played by a Player

engine.errors module

Errors for the Ultimate TicTacToe Engine

exception engine.errors.BoardNotFinishedError[source]

Bases: engine.errors.Error

exception engine.errors.Error[source]

Bases: Exception

Base class for exceptions

exception engine.errors.MoveInFinishedBoardError(board_coords, player)[source]

Bases: engine.errors.Error

exception engine.errors.MoveInPlayedCellError(player, sub_board_coords, main_board_coords=None)[source]

Bases: engine.errors.Error

exception engine.errors.MoveNotOnNextBoardError(main_board_coords: engine.gameplay.MainBoardCoords, sub_board_next_player_must_play)[source]

Bases: engine.errors.Error

exception engine.errors.MoveOutsideMainBoardError(main_board_coords: engine.gameplay.MainBoardCoords)[source]

Bases: engine.errors.Error

exception engine.errors.MoveOutsideSubBoardError(sub_board_coords)[source]

Bases: engine.errors.Error

engine.gameplay module

class engine.gameplay.MainBoardCoords(main_board_row, main_board_col)[source]

Bases: engine.gameplay.SubBoardCoords

Convenience wrapper to represent MainBoard co-ordinates (referencing a SubBoard)

class engine.gameplay.SubBoardCoords(row, col)[source]

Bases: object

Move co-ordinates (in a SubBoard)

engine.gameplay.did_move_win(board: [[<class 'engine.cell.Cell'>]], board_coords: engine.gameplay.SubBoardCoords, player: engine.player.Player) → bool[source]

Whether the given player move was a winning move (this assumes that the move is already present in the board)

engine.gameplay.is_cell_range_played_by(cells: [[<class 'engine.cell.Cell'>]], player: engine.player.Player) → bool[source]

Whether the given list of cells are all played by the given player

Args:
cells: The list of cells to check player: The player to look for
engine.gameplay.is_col_won(board: [[<class 'engine.cell.Cell'>]], board_coords: engine.gameplay.SubBoardCoords, player: engine.player.Player) → bool[source]

Whether the column of the player move is won by the player of the move

engine.gameplay.is_diagonal_won(board: [[<class 'engine.cell.Cell'>]], player: engine.player.Player) → bool[source]

Whether either diagonal from the cell of the player move is won by the player

engine.gameplay.is_ltr_diagonal_won(board: [[<class 'engine.cell.Cell'>]], player: engine.player.Player) → bool[source]

Whether the left to right (0,0) to (2,2) diagonal has been won by the given player

engine.gameplay.is_row_won(board: [[<class 'engine.cell.Cell'>]], board_coords: engine.gameplay.SubBoardCoords, player: engine.player.Player) → bool[source]

Whether the row of the player move is won by the player of the move

engine.gameplay.is_rtl_diagonal_won(board: [[<class 'engine.cell.Cell'>]], player: engine.player.Player) → bool[source]

Whether the left to right (2,0) to (0,2) diagonal has been won by the given player

engine.main_board module

class engine.main_board.MainBoard(board_size: int = 3)[source]

Bases: object

An Ultimate TicTacToe board, containing several SubBoards where players play

When the board size is 3, the main board looks like this:

| SubBoard 0,0 | SubBoard 0,1 | SubBoard 0,2 |
| SubBoard 1,0 | SubBoard 1,1 | SubBoard 1,2 |
| SubBoard 2,0 | SubBoard 2,1 | SubBoard 2,2 |

Each SubBoard looks like this:

| Cell 0,0 | Cell 0,1 | Cell 0,2 |
| Cell 1,0 | Cell 1,1 | Cell 1,2 |
| Cell 2,0 | Cell 2,1 | Cell 2,2 |
add_my_move(main_board_coords: engine.gameplay.MainBoardCoords, sub_board_coords: engine.gameplay.SubBoardCoords) → engine.main_board.MainBoard[source]

Adds your move to the specified sub-board

Args:
main_board_coords: The co-ordinates (row, column) of the SubBoard to play on move: The move (row, column) to make on the SubBoard
Returns:
A new MainBoard instance with the move applied
add_opponent_move(main_board_coords: engine.gameplay.MainBoardCoords, sub_board_coords: engine.gameplay.SubBoardCoords) → engine.main_board.MainBoard[source]

Adds the opponent’s move to the specified sub-board

Args:
main_board_coords: The co-ordinates (row, column) of the SubBoard to play on sub_board_coords: The move (row, column) to make on the SubBoard
Returns:
A new MainBoard instance with the move applied
copy_applying_move(main_board_coords, sub_board_coords, player) → engine.main_board.MainBoard[source]
get_playable_coords() → [<class 'engine.gameplay.MainBoardCoords'>][source]

Returns all board co-ordinates that are valid for the next move.

If the opponents previous move co-ordinates (according to the rules) restrict you to a single sub-board, then this will return only that board. If not, it will return all boards that are valid for moves.

Returns Empty if board is finished.

Returns:
Array of valid board co-ordinates (Row, Col), e.g. [MainBoardCoords(2, 2),MainBoardCoords(1, 1)]
get_sub_board(main_board_coords: engine.gameplay.MainBoardCoords) → engine.sub_board.SubBoard[source]
is_finished

Whether the board is finished (tied, won or lost)

is_playing_on_sub_board_allowed(main_board_coords: engine.gameplay.MainBoardCoords)[source]

Whether this is a valid board for the next move

Args:
main_board_coords: The co-ordinates (row, column) of the SubBoard to check
sub_board_next_player_must_play

The next board to play on. None if the next move can be on any board

winner

The winner of the board if finished. Exception otherwise

engine.player module

class engine.player.Player[source]

Bases: enum.Enum

Identifiers for players

ME = 1
NONE = 0
ONE = 1
OPPONENT = 2
TWO = 2

engine.sub_board module

class engine.sub_board.SubBoard(board_size: int = 3)[source]

Bases: object

A single game of TicTacToe (not ultimate). Several of these make up the Ultimate TTT game.

Instances of this class behave in a functional manner, with no method call modifying the state of the original object. State changing operations (such as add_my_move) return a new SubBoard object, which the calling function must replace. The returned SubBoard object has all properties (e.g. is_finished) calculated.

Example:

SubBoard(3) #Initialises a board of size 3
    .add_my_move(SubBoardCoords(1, 1)) #Adds a move at 1, 1 and returns a SubBoard
    .add_opponent_move(SubBoardCoords(2, 1)) #Adds a move to the last returned board

Call str(SubBoard()) to get a pretty-printed representation of this board

Todo:
  • Use a @classmethod to initialize SubBoard and make it immutable internally
add_move(sub_board_coords: engine.gameplay.SubBoardCoords, player: engine.player.Player) → engine.sub_board.SubBoard[source]

Adds a move by a ultimate_ttt_player to a deep copy of the board, returning the copy

Player may find it easier to use the add_my_move() and add_opponent_move() functions

Args:
sub_board_coords: The co-ordinates to make a move in on this sub-board player: The player that made the move
Returns:
A new SubBoard instance with the move applied and all properties calculated
add_my_move(sub_board_coords: engine.gameplay.SubBoardCoords) → engine.sub_board.SubBoard[source]

Adds a move for the current player

Args:
sub_board_coords: Move co-ordinates
Returns:
A new SubBoard instance with the move applied
add_opponent_move(sub_board_coords: engine.gameplay.SubBoardCoords) → engine.sub_board.SubBoard[source]

Adds a move for the opponent

Args:
sub_board_coords: Move co-ordinates
Returns:
A new SubBoard instance with the move applied
get_playable_coords() → [<class 'engine.gameplay.SubBoardCoords'>][source]
Returns:

All valid SubBoardCoords that can be played (have not been played

Empty if board is finished.

is_finished

Whether the board is finished (tied, won or lost)

winner

The winner of the board if finished. Exception otherwise

Module contents