Connect Four v0.1.2 ConnectFour.Game View Source
A Connect Four game.
Players are distinguished by game piece color (yellow and red). Moves are represented by the columns in which they are made.
Yellow moves first.
This implementation is based on an efficient implementation written by John Tromp, which uses bitboards to be very small and very fast.
This is how it works: https://github.com/denkspuren/BitboardC4/blob/master/BitboardDesign.md
Original Java implementation: https://tromp.github.io/c4/Connect4.java
Link to this section Summary
Types
One of seven Connect Four game columns.
A list of Connect Four moves, describing a game.
A Connect Four player (yellow always moves first).
A Connect Four game result. nil
means that the game has not yet ended. :draw
s occur when all
columns are full and no player has connected four.
Functions
Returns a specification to start this module under a supervisor.
Get a list of legal moves for the current position.
Look at the state of the game.
Submit a move for whomever's turn it currently is by specifying a column (0 through 6).
Restart the game. The game does not need to have a result to be restarted.
Start a GenServer process for a Connect Four game.
Link to this section Types
One of seven Connect Four game columns.
A list of Connect Four moves, describing a game.
A Connect Four player (yellow always moves first).
A Connect Four game result. nil
means that the game has not yet ended. :draw
s occur when all
columns are full and no player has connected four.
t()
View Sourcet() :: %ConnectFour.Game{ bitboards: %{yellow: integer(), red: integer()}, column_heights: column_heights(), moves: moves(), plies: non_neg_integer(), result: result() }
Link to this section Functions
Returns a specification to start this module under a supervisor.
See Supervisor
.
Get a list of legal moves for the current position.
Examples
iex> {:ok, pid} = Game.start_link()
iex> Game.legal_moves(pid)
{:ok, [0, 1, 2, 3, 4, 5, 6]}
iex> {:ok, pid} = Game.start_link()
iex> Game.move(pid, [3, 3, 3, 3, 3, 3])
{:ok, %{moves: [3, 3, 3, 3, 3, 3], result: nil}}
iex> Game.legal_moves(pid)
{:ok, [0, 1, 2, 4, 5, 6]}
Look at the state of the game.
Examples
iex> {:ok, pid} = Game.start_link()
iex> Game.move(pid, [4, 5, 4])
{:ok, %{moves: [4, 5, 4], result: nil}}
iex> Game.look(pid)
{:ok, %{moves: [4, 5, 4], result: nil}}
Works for finished games, too.
Examples
iex> {:ok, pid} = Game.start_link()
iex> Game.move(pid, [4, 5, 4, 5, 4, 5])
{:ok, %{moves: [4, 5, 4, 5, 4, 5], result: nil}}
iex> Game.move(pid, 4)
{:ok, %{moves: [4, 5, 4, 5, 4, 5, 4], result: :yellow_wins}}
iex> Game.look(pid)
{:ok, %{moves: [4, 5, 4, 5, 4, 5, 4], result: :yellow_wins}}
Submit a move for whomever's turn it currently is by specifying a column (0 through 6).
Make multiple moves at once by passing a list of moves. If any of the moves are invalid, none (including any valid ones preceding the invalid one) will be played.
moves
is a list of all the moves completed in the game so far. Moves are
represented as integers between 0 and 6, each reflecting the column in which
the piece for that turn was dropped. The first integer in the list is yellow's
move, the second is red's, the third is yellow's, and so on.
Game results are reported as atoms and can be one of the following:
nil
(when the game is still in progress):yellow_wins
:red_wins
:draw
(when the board fills up without four connected pieces)
Examples
iex> {:ok, pid} = Game.start_link()
iex> Game.move(pid, 4)
{:ok, %{moves: [4], result: nil}}
iex> Game.move(pid, 5)
{:ok, %{moves: [4, 5], result: nil}}
iex> {:ok, pid} = Game.start_link()
iex> Game.move(pid, [4, 5])
{:ok, %{moves: [4, 5], result: nil}}
iex> {:ok, pid} = Game.start_link()
iex> Game.move(pid, [4, 7])
{:error, "One or more invalid moves"}
iex> {:ok, pid} = Game.start_link()
iex> Game.move(pid, [1, 1, 2, 2, 3, 3, 4])
{:ok, %{moves: [1, 1, 2, 2, 3, 3, 4], result: :yellow_wins}}
iex> Game.move(pid, 4)
{:error, "Game is over"}
Restart the game. The game does not need to have a result to be restarted.
Examples
iex> {:ok, pid} = Game.start_link()
iex> Game.move(pid, 4)
{:ok, %{moves: [4], result: nil}}
iex> Game.restart(pid)
:ok
iex> Game.move(pid, 4)
{:ok, %{moves: [4], result: nil}}
Start a GenServer process for a Connect Four game.
Examples
iex> {:ok, pid} = Game.start_link()
iex> Process.alive?(pid)
true