Packages
islands_engine
0.2.29
0.2.65
0.2.64
0.2.63
0.2.62
0.2.61
0.2.60
0.2.59
0.2.58
0.2.56
0.2.55
0.2.54
0.2.53
0.2.52
0.2.51
0.2.50
0.2.49
0.2.48
0.2.47
0.2.46
0.2.45
0.2.44
0.2.43
0.2.42
0.2.41
0.2.40
0.2.39
0.2.38
0.2.37
0.2.36
0.2.35
0.2.34
0.2.33
0.2.32
0.2.31
0.2.30
0.2.29
0.2.28
0.2.27
0.2.25
0.2.24
0.2.23
0.2.22
0.2.21
0.2.20
0.2.19
0.2.18
0.2.17
0.2.16
0.2.15
0.2.13
0.2.12
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.81
0.1.80
0.1.79
0.1.78
0.1.77
0.1.76
0.1.75
0.1.73
0.1.72
0.1.71
0.1.70
0.1.69
0.1.68
0.1.67
0.1.66
0.1.65
0.1.64
0.1.63
0.1.62
0.1.61
0.1.60
0.1.59
0.1.58
0.1.57
0.1.56
0.1.55
0.1.54
0.1.53
0.1.52
0.1.51
0.1.50
0.1.49
0.1.48
0.1.47
0.1.46
0.1.45
0.1.44
0.1.43
0.1.42
0.1.41
0.1.40
0.1.39
0.1.38
0.1.37
0.1.36
0.1.35
0.1.34
0.1.33
0.1.32
0.1.31
0.1.30
0.1.29
0.1.28
0.1.27
0.1.26
0.1.25
0.1.24
0.1.23
0.1.22
0.1.21
0.1.20
0.1.19
0.1.18
0.1.17
0.1.16
0.1.15
0.1.14
0.1.13
0.1.12
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.0
Models the Game of Islands.
Current section
Files
Jump to
Current section
Files
lib/islands/engine.ex
# ┌────────────────────────────────────────────────────────────────────┐
# │ Based on the book "Functional Web Development" by Lance Halvorsen. │
# └────────────────────────────────────────────────────────────────────┘
defmodule Islands.Engine do
use GenServer.Proxy
use PersistConfig
@book_ref Application.get_env(@app, :book_ref)
@moduledoc """
Models the _Game of Islands_.
\n##### #{@book_ref}
"""
import Islands.Engine.Guards
alias Islands.Engine.{DynSup, Server}
alias Islands.{Coord, Island, Player, PlayerID, Tally}
@doc """
Starts a new game.
"""
@spec new_game(String.t(), String.t(), Player.gender(), pid) ::
Supervisor.on_start_child()
def new_game(game_name, player1_name, gender, pid)
when valid_player_args(game_name, player1_name, gender, pid) do
child_spec = {Server, {game_name, player1_name, gender, pid}}
DynamicSupervisor.start_child(DynSup, child_spec)
end
@doc """
Ends a game.
"""
@spec end_game(String.t()) :: :ok
def end_game(game_name) when is_binary(game_name),
do: stop(:shutdown, game_name)
@doc """
Stops a game.
"""
@spec stop_game(String.t(), PlayerID.t()) :: Tally.t() | :ok
def stop_game(game_name, player_id)
when valid_player_args(game_name, player_id),
do: call({:stop, player_id}, game_name)
@doc """
Adds the second player of a game.
"""
@spec add_player(String.t(), String.t(), Player.gender(), pid) ::
Tally.t() | :ok
def add_player(game_name, player2_name, gender, pid)
when valid_player_args(game_name, player2_name, gender, pid),
do: call({:add_player, player2_name, gender, pid}, game_name)
@doc """
Positions an island on the specified player's board.
"""
@spec position_island(
String.t(),
PlayerID.t(),
Island.type(),
Coord.row(),
Coord.col()
) :: Tally.t() | :ok
def position_island(game_name, player_id, island_type, row, col)
when valid_island_args(game_name, player_id, island_type, row, col),
do: call({:position_island, player_id, island_type, row, col}, game_name)
@doc """
Positions all islands on the specified player's board.
"""
@spec position_all_islands(String.t(), PlayerID.t()) :: Tally.t() | :ok
def position_all_islands(game_name, player_id)
when valid_player_args(game_name, player_id),
do: call({:position_all_islands, player_id}, game_name)
@doc """
Declares all islands set for the specified player.
"""
@spec set_islands(String.t(), PlayerID.t()) :: Tally.t() | :ok
def set_islands(game_name, player_id)
when valid_player_args(game_name, player_id),
do: call({:set_islands, player_id}, game_name)
@doc """
Allows the specified player to guess a coordinate.
"""
@spec guess_coord(String.t(), PlayerID.t(), Coord.row(), Coord.col()) ::
Tally.t() | :ok
def guess_coord(game_name, player_id, row, col)
when valid_coord_args(game_name, player_id, row, col),
do: call({:guess_coord, player_id, row, col}, game_name)
@doc """
Allows to update the specified player.
"""
@spec update_player(
String.t(),
PlayerID.t(),
String.t(),
Player.gender(),
pid
) :: Tally.t() | :ok
def update_player(game_name, player_id, player_name, gender, pid)
when valid_player_args(game_name, player_id, player_name, gender, pid),
do: call({:update_player, player_id, player_name, gender, pid}, game_name)
@doc """
Returns the tally of the game for the specified player.
"""
@spec tally(String.t(), PlayerID.t()) :: Tally.t() | :ok
def tally(game_name, player_id)
when valid_player_args(game_name, player_id),
do: call({:tally, player_id}, game_name)
@doc """
Returns a sorted list of registered game names.
"""
@spec game_names :: [String.t()]
def game_names do
:global.registered_names()
|> Enum.filter(&(is_tuple(&1) and elem(&1, 0) == Server))
|> Enum.map(&elem(&1, 1))
end
@doc """
Returns the `pid` of the game server process registered under the
given `game_name`, or `nil` if no such process is registered.
"""
@spec game_pid(String.t()) :: pid | nil
def game_pid(game_name), do: game_name |> Server.via() |> GenServer.whereis()
end