Packages
islands_engine
0.1.11
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/state.ex
# State machine...
defmodule Islands.Engine.State do
@moduledoc false
@behaviour Access
use PersistConfig
alias __MODULE__
alias Islands.Engine.Game
defstruct game: :initialized,
player1: :islands_not_set,
player2: :islands_not_set
@type game_state ::
:initialized
| :players_set
| :player1_turn
| :player2_turn
| :game_over
@type player_state :: :islands_not_set | :islands_set
@type t :: %State{
game: game_state,
player1: player_state,
player2: player_state
}
@typep request ::
:add_player
| {:position_island, Game.player_id()}
| {:position_all_islands, Game.player_id()}
| {:set_islands, Game.player_id()}
| {:guess_coord, Game.player_id()}
| {:win_check, win_status}
| :stop
@typep win_status :: :no_win | :win
@player_ids Application.get_env(@app, :player_ids)
@player_turns [:player1_turn, :player2_turn]
@position_actions [:position_island, :position_all_islands]
# Access behaviour
defdelegate fetch(state, key), to: Map
defdelegate get(state, key, default), to: Map
defdelegate get_and_update(state, key, fun), to: Map
defdelegate pop(state, key), to: Map
@spec new() :: t
def new(), do: %State{}
@spec check(t, request) :: {:ok, t} | :error
def check(%State{game: :initialized} = state, :add_player) do
{:ok, put_in(state.game, :players_set)}
end
def check(%State{game: :players_set} = state, {action, player_id})
when action in @position_actions and player_id in @player_ids do
case state[player_id] do
:islands_set -> :error
:islands_not_set -> {:ok, state}
end
end
def check(%State{game: :players_set} = state, {:set_islands, player_id})
when player_id in @player_ids do
state = put_in(state[player_id], :islands_set)
if both_players_islands_set?(state),
do: {:ok, put_in(state.game, :player1_turn)},
else: {:ok, state}
end
def check(%State{game: :player1_turn} = state, {:guess_coord, :player1}) do
{:ok, put_in(state.game, :player2_turn)}
end
def check(%State{game: :player2_turn} = state, {:guess_coord, :player2}) do
{:ok, put_in(state.game, :player1_turn)}
end
def check(%State{game: player_turn} = state, {:win_check, :no_win})
when player_turn in @player_turns do
{:ok, state}
end
def check(%State{game: player_turn} = state, {:win_check, :win})
when player_turn in @player_turns do
{:ok, put_in(state.game, :game_over)}
end
def check(%State{game: player_turn} = state, :stop)
when player_turn in @player_turns do
{:ok, put_in(state.game, :game_over)}
end
def check(_state, _request), do: :error
## Private functions
@spec both_players_islands_set?(t) :: boolean
defp both_players_islands_set?(state) do
state.player1 == :islands_set and state.player2 == :islands_set
end
end