Tabletop (tabletop v1.1.2)

Tabletop contains functions for playing a board game and querying the state of the game.

Taking Turns

Taking a turn involves calling the take_turn/2 function which follows these steps:

  1. Apply provided actions - e.g. add a piece, move a piece
  2. Apply board effects - e.g. check if a player has won
  3. Increment the turn counter

To find out more about actions or effects, check the Tabletop.Actions or Tabletop.Board modules respectively.

Link to this section Summary

Functions

Returns the piece on the board at position.

Checks if the provided position is within the bounds of the board.

Lazily moves through positions on the board starting from starting_position and returns sets of neighbouring positions. Each element will be a tuple containing two positions.

Checks if the provided position on the board is occupied by a piece.

Finds the position of the first matching piece on the board. If no piece is found, default is returned.

Applies the provided actions to the board and then advances to the next turn. Actions consist of a combination of the following

Lazily moves through positions on the board starting from starting_position. Each element returned be a Tuple containing the position and piece at that position.

Link to this section Functions

Link to this function

get_piece(board, position)

Specs

get_piece(atom() | %{:pieces => map(), optional(any()) => any()}, any()) ::
  any()

Returns the piece on the board at position.

Examples

iex> Tabletop.Board.square(3)
iex>   |> Tabletop.Actions.apply(:add,  {Tabletop.Piece.new("Rook"), {0, 0}})
iex>   |> Tabletop.get_piece({0, 0})
%Tabletop.Piece{id: "Rook"}

iex> Tabletop.Board.square(3)
iex>   |> Tabletop.get_piece({1, 0})
nil
Link to this function

in_bounds?(board, position)

Checks if the provided position is within the bounds of the board.

Examples

iex> Tabletop.Board.square(3)
iex>   |> Tabletop.in_bounds?({0, 0})
true

iex> Tabletop.Board.square(3)
iex>   |> Tabletop.in_bounds?({99, 99})
false
Link to this function

neighbours(board, starting_position, fun)

Lazily moves through positions on the board starting from starting_position and returns sets of neighbouring positions. Each element will be a tuple containing two positions.

Invokes fun with the current position in order to determine the positions of neighbours.

Once every set of neighbouring positions are covered, no more elements will be returned.

Examples

iex> Tabletop.Board.square(3)
iex>   |> Tabletop.neighbours({0, 0}, &Tabletop.Grid.cardinal_points/1)
iex>   |> Enum.take(2)
[{{0, 0}, {1, 0}}, {{0, 0}, {0, 1}}]
Link to this function

occupied?(board, position)

Checks if the provided position on the board is occupied by a piece.

Examples

iex> Tabletop.Board.square(3)
iex>   |> Tabletop.Actions.apply(:add, {Tabletop.Piece.new("Rook"), {0, 0}})
iex>   |> Tabletop.occupied?({0, 0})
true
Link to this function

position_of(board, piece, default \\ nil)

Finds the position of the first matching piece on the board. If no piece is found, default is returned.

Examples

iex> Tabletop.Board.square(3)
iex>   |> Tabletop.position_of(Tabletop.Piece.new("Pawn"), :unknown)
:unknown

iex> piece = Tabletop.Piece.new("Pawn")
iex> Tabletop.Board.square(3)
iex>   |> Tabletop.Actions.apply(:add, {piece, {0, 0}})
iex>   |> Tabletop.position_of(piece)
{0,0}
Link to this function

take_turn(board, actions)

Applies the provided actions to the board and then advances to the next turn. Actions consist of a combination of the following:

  • :move => {from, to}
  • :add => {piece, position}
  • :remove => position
  • :assign => {position, attributes}

For example, a Chess turn might see a single :move action or two :move actions in the case of castling.

Examples

iex> %Tabletop.Board{}
iex>   |> Tabletop.take_turn(%{})
%Tabletop.Board{turn: 2}

iex> Tabletop.Board.square(3)
iex>   |> Tabletop.take_turn(add: {Tabletop.Piece.new("Rook"), {0, 0}})
iex>   |> Tabletop.take_turn(move: {{0, 0}, {0, 1}})
iex>   |> Tabletop.get_piece({0, 1})
%Tabletop.Piece{id: "Rook"}
Link to this function

travel(board, starting_position, fun)

Lazily moves through positions on the board starting from starting_position. Each element returned be a Tuple containing the position and piece at that position.

Invokes fun with the current position in order to determine the next position.

If the position does not contain a piece, the second element of the returned Tuple will be nil instead.

Once the position is out of bounds, no more elements will be returned.

Examples

iex> Tabletop.Board.square(3)
iex>   |> Tabletop.travel({0, 0}, fn {x, y} -> {x + 1, y + 1} end)
iex>   |> Enum.to_list()
[{{0, 0}, nil}, {{1, 1}, nil}, {{2, 2}, nil}]