Game Interface
AlphaZero.GameInterface
— ModuleA generic interface for two-players, symmetric, zero-sum games.
We call a game symmetric when the rules are the same for both players. Said differently, it is always possible to swap the players' colors along with the color of every piece on the board without affecting the game.
Mandatory Interface
Types
AlphaZero.GameInterface.AbstractGame
— TypeAbstractGame
Abstract base type for a game state.
Constructors
Any subtype Game
must implement Base.copy
along with the following constructors:
Game()
Return the initial state of the game.
Game(board, white_playing=true)
Return the unique state specified by a board and a current player. By convention, the first player to play is called white and the other is called black.
AlphaZero.GameInterface.Board
— FunctionBoard(Game::Type{<:AbstractGame})
Return the board type corresponding to Game
.
Board objects must be persistent or appear as such as they are stored into the MCTS tree without copying.
Remark
A game state (of type AbstractGame
) is characterized by two pieces of information: the board state and the identity of the player to play next. There are two reasons for having a separate Board
type:
- This separation allows the
Game
object to store redundant state information, typically for caching expensive computations. - This separation enables leveraging the symmetry between players by storing every board in the MCTS tree from the perspective of the current player (as if white were to play next).
AlphaZero.GameInterface.Action
— FunctionAction(Game::Type{<:AbstractGame})
Return the action type corresponding to Game
.
Actions must be colorblind in the following sense:
available_actions(s) == available_actions(state_symmetric(s))
Game Functions
AlphaZero.GameInterface.white_playing
— Functionwhite_playing(state::AbstractGame) :: Bool
Return true
if white is to play and false
otherwise.
AlphaZero.GameInterface.white_reward
— Functionwhite_reward(state::AbstractGame)
Return nothing
if the game hasn't ended. Otherwise, return a reward for the white player as a number between -1 and 1.
AlphaZero.GameInterface.board
— Functionboard(state::AbstractGame)
Return the game board.
AlphaZero.GameInterface.board_symmetric
— Functionboard_symmetric(state::AbstractGame)
Return the symmetric of the game board, where the players' colors are swapped.
The white player must have opposite values in state
and state_symmetric(state)
.
AlphaZero.GameInterface.actions
— Functionactions(::Type{<:AbstractGame})
Return the vector of all game actions.
AlphaZero.GameInterface.actions_mask
— Functionactions_mask(state::AbstractGame)
Return a boolean mask indicating what actions are available from state
.
The following identities must hold:
game_terminated(state) || any(actions_mask(state))
length(actions_mask(state)) == length(actions(typeof(state)))
AlphaZero.GameInterface.play!
— Functionplay!(state::AbstractGame, action)
Update the game state by making the current player perform action
.
AlphaZero.GameInterface.heuristic_value
— Functionheuristic_value(state::AbstractGame)
Return a heuristic estimate of the state value for the current player.
The given state must be nonfinal and returned values must belong to the $(-∞, ∞)$ interval. Also, the following must hold:
heuristic_value(s) == heuristic_value(state_symmetric(s))
This function is not needed by AlphaZero but it is useful for building baselines such as minmax players.
AlphaZero.GameInterface.vectorize_board
— Functionvectorize_board(::Type{<:AbstractGame}, board) :: Array{Float32}
Return a vectorized representation of a board.
AlphaZero.GameInterface.symmetries
— Functionsymmetries(::Type{G}, board) where {G <: AbstractGame}
Return the vector of all pairs (b, σ)
where:
b
is the image ofboard
by a nonidentical symmetryσ
is the associated actions permutation, as an integer vector of sizenum_actions(Game)
.
A default implementation is provided that returns an empty vector.
Note
This function should not be confused with board_symmetric
.
board_symmetric
only deals with color symmetry (the rules of the game are the same for both players). Its implementation is mandatory and leveraged by MCTS.symmetries
can be used to declare additional symmetries, typically about board geometry (ie. a tictactoe grid is invariant by rotation).
Interface for Interactive Tools
AlphaZero.GameInterface.action_string
— Functionaction_string(::Type{<:AbstractGame}, action) :: String
Return a human-readable string representing the provided action.
AlphaZero.GameInterface.parse_action
— Functionparse_action(::Type{<:AbstractGame}, str::String)
Return the action described by string str
or nothing
if str
does not denote a valid action.
AlphaZero.GameInterface.read_state
— Functionread_state(::Type{G}) where G <: AbstractGame :: Union{G, Nothing}
Read a state description from the standard input. Return the corresponding state or nothing
in case of an invalid input.
AlphaZero.GameInterface.print_state
— Functionprint_state(state::AbstractGame)
Print a state on the standard output.
Derived Functions
AlphaZero.GameInterface.state_symmetric
— Functionstate_symmetric(state)
Return a fresh symmetric state where the players' colors are swapped. See board_symmetric
.
AlphaZero.GameInterface.game_terminated
— Functiongame_terminated(::AbstractGame)
Return a boolean indicating whether or not a game is in a terminal state.
AlphaZero.GameInterface.num_actions
— Functionnum_actions(::Type{G})
Return the total number of actions associated with a game.
AlphaZero.GameInterface.available_actions
— Functionavailable_actions(state::AbstractGame)
Return the vector of all available actions in a given state.
AlphaZero.GameInterface.board_dim
— Functionboard_dim(::Type{G})
Return a tuple that indicates the shape of a vectorized board representation.
AlphaZero.GameInterface.random_symmetric_state
— Functionrandom_symmetric_state(::AbstractGame)
Return a fresh new state that is the image of the given state by a random symmetry (see symmetries
).