ExChess.Game (ExChess v0.1.0)

View Source

The ExChess.Game struct is an aggregate of the entirety of the state required to keep track of the game, and evaluate all chess rules.

Summary

Types

Castling is only allowed when neither the rook nor the king have previously moved throughout the game. Each castle starts with a value of true, and whenever a king or rook is moved, the corresponding castles are set to false.

The en passant file keeps track of any file where a pawn has advanced two squares and is vulnerable to en passant. This value is set regardless of whether another pawn is in position to attack. If the last halfmove was anything other than a pawn advancing two squares, the en passant file is nil.

Keeps track of the number of fullmoves. A fullmove is incremented by 1 after every move by :black.

The halfmove clock keeps track of the number of irreversible moves in a row that have occured. This is then used to evaluate whether or not the 50 move rule and/or the 75 move rule apply.

Keeps track of the maximum count present in the repetition history for easier evaluation of threefold/fivefold repetition.

This is used to keep count of all positions that have already been played, in order to evaluate the threefold/fivefold repetition rules. The map is reset any time an irreversible move is played, as that guarantees that position will never be repeated.

The game status.

t()

The ExChess.Game struct is an aggregate of the entirety of the state required to keep track of the game, and evaluate all chess rules.

Functions

Returns a map with all castling rights set to false.

Creates a new game with all the default state.

Types

castling_rights()

@type castling_rights() :: %{
  white_kingside?: boolean(),
  white_queenside?: boolean(),
  black_kingside?: boolean(),
  black_queenside?: boolean()
}

Castling is only allowed when neither the rook nor the king have previously moved throughout the game. Each castle starts with a value of true, and whenever a king or rook is moved, the corresponding castles are set to false.

en_passant_file()

@type en_passant_file() :: non_neg_integer() | nil

The en passant file keeps track of any file where a pawn has advanced two squares and is vulnerable to en passant. This value is set regardless of whether another pawn is in position to attack. If the last halfmove was anything other than a pawn advancing two squares, the en passant file is nil.

fullmove_number()

@type fullmove_number() :: pos_integer()

Keeps track of the number of fullmoves. A fullmove is incremented by 1 after every move by :black.

halfmove_clock()

@type halfmove_clock() :: non_neg_integer()

The halfmove clock keeps track of the number of irreversible moves in a row that have occured. This is then used to evaluate whether or not the 50 move rule and/or the 75 move rule apply.

max_repetitions()

@type max_repetitions() :: pos_integer()

Keeps track of the maximum count present in the repetition history for easier evaluation of threefold/fivefold repetition.

repetition_history()

@type repetition_history() :: %{
  required({ExChess.Piece.color(), non_neg_integer()}) => pos_integer()
}

This is used to keep count of all positions that have already been played, in order to evaluate the threefold/fivefold repetition rules. The map is reset any time an irreversible move is played, as that guarantees that position will never be repeated.

The key is a tuple containing two elements: the active color and a hash of the board state, those two values are enough to identify each unique position. The values are of course the count of repetitions for said position.

status()

@type status() ::
  :continue
  | {ExChess.Piece.color(), :checkmate | :resignation}
  | {:tie,
     :stalemate
     | :insufficient_material
     | :threefold_repetition
     | :fivefold_repetition
     | :fifty_move_rule
     | :seventy_five_move_rule}

The game status.

:continue is the default state, it represents a game that is still in progress. {Piece.color(), _reason} is used when one of the players has been declared winner. {:tie, _reason} means the game ended in a draw.

t()

@type t() :: %ExChess.Game{
  active_color: ExChess.Piece.color(),
  board: ExChess.Board.t(),
  castling_rights: castling_rights(),
  en_passant_file: en_passant_file(),
  fullmove_number: fullmove_number(),
  halfmove_clock: halfmove_clock(),
  max_repetitions: max_repetitions(),
  repetition_history: repetition_history(),
  status: status()
}

The ExChess.Game struct is an aggregate of the entirety of the state required to keep track of the game, and evaluate all chess rules.

Functions

empty_castling_rights()

This function is deprecated. This is only used in two places and I am not yet sure I want to expose it in the public API..
@spec empty_castling_rights() :: castling_rights()

Returns a map with all castling rights set to false.

new()

@spec new() :: t()

Creates a new game with all the default state.

Examples

iex> ExChess.Game.new()
...> |> ExChess.Visualization.game()
"STATUS: * | FEN: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"

new(active_color, board, castling_rights \\ nil, en_passant_file \\ nil, halfmove_clock \\ 0, fullmove_number \\ 1)

Creates a new game.

Examples

iex> ExChess.Game.new(:white, ExChess.Fen.to_board("knn5/8/8/8/8/8/8/KNN5"), nil, 3, 40)
...> |> ExChess.Fen.from_game()
"knn5/8/8/8/8/8/8/KNN5 w - d4 40 1"