Packages
islands_engine
0.2.8
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/game/state.ex
defmodule Islands.Engine.Game.State do
@moduledoc "State machine..."
@behaviour Access
use PersistConfig
alias __MODULE__
alias Islands.Engine.Game
defstruct game_state: :initialized,
player1_state: :islands_not_set,
player2_state: :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_state: game_state,
player1_state: player_state,
player2_state: 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, :no_win | :win}
| :stop
@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_state: :initialized} = state, :add_player),
do: {:ok, put_in(state.game_state, :players_set)}
def check(%State{game_state: :players_set} = state, {action, player_id})
when action in @position_actions and player_id in @player_ids do
case state[state_key(player_id)] do
:islands_not_set -> {:ok, state}
:islands_set -> :error
end
end
def check(%State{game_state: :players_set} = state, {:set_islands, player_id})
when player_id in @player_ids do
state = put_in(state[state_key(player_id)], :islands_set)
if both_players_islands_set?(state),
do: {:ok, put_in(state.game_state, :player1_turn)},
else: {:ok, state}
end
def check(
%State{game_state: :player1_turn} = state,
{:guess_coord, :player1}
),
do: {:ok, put_in(state.game_state, :player2_turn)}
def check(
%State{game_state: :player2_turn} = state,
{:guess_coord, :player2}
),
do: {:ok, put_in(state.game_state, :player1_turn)}
def check(%State{game_state: player_turn} = state, {:win_check, :no_win})
when player_turn in @player_turns,
do: {:ok, state}
def check(%State{game_state: player_turn} = state, {:win_check, :win})
when player_turn in @player_turns,
do: {:ok, put_in(state.game_state, :game_over)}
def check(%State{game_state: player_turn} = state, :stop)
when player_turn in @player_turns,
do: {:ok, put_in(state.game_state, :game_over)}
def check(_state, _request), do: :error
## Private functions
@spec both_players_islands_set?(t) :: boolean
defp both_players_islands_set?(state) do
state.player1_state == :islands_set and state.player2_state == :islands_set
end
@spec state_key(Game.player_id()) :: atom
defp state_key(player_id), do: :"#{player_id}_state"
end