Packages
islands_client_input
0.1.32
0.1.49
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.3
0.1.2
0.1.1
0.1.0
Prompts and accepts a move in the Game of Islands.
Current section
Files
Jump to
Current section
Files
lib/islands/client/input/parser.ex
defmodule Islands.Client.Input.Parser do
@moduledoc """
Parses the prompted input and, if valid, updates the client state struct.
"""
use PersistConfig
alias Islands.Client.Input.Prompter
alias Islands.Client.{GameOver, Input, RandomGuess, State}
@coord_range 1..10
@island_type_codes ["a", "d", "l", "s", "q"]
@messages get_env(:messages)
@pause_range 0..10_000
@doc """
Parses the prompted input and, if valid, updates the client state struct.
"""
@spec parse_input(Input.t(), State.t()) :: State.t() | no_return
def parse_input({:error, reason} = _input, state),
do: GameOver.end_game(["Game ended: #{inspect(reason)}"], state)
def parse_input(:eof = input, state),
do: GameOver.end_game(["Game ended: #{inspect(input)}"], state)
def parse_input(input, %State{} = state) do
input
|> String.split()
|> case do
[code, row, col] when code in @island_type_codes ->
with {row, ""} when row in @coord_range <- Integer.parse(row),
{col, ""} when col in @coord_range <- Integer.parse(col) do
put_in(state.move, [code, row, col])
else
_ -> Prompter.accept_move(state, @messages.bad_move)
end
["auto", pause] ->
with {pause, ""} when pause in @pause_range <- Integer.parse(pause) do
%State{state | mode: :auto, pause: pause}
|> Prompter.accept_move(@messages.auto_mode)
else
_ -> Prompter.accept_move(state, @messages.bad_move)
end
[row, col] ->
with {row, ""} when row in @coord_range <- Integer.parse(row),
{col, ""} when col in @coord_range <- Integer.parse(col) do
put_in(state.move, [row, col])
else
_ -> Prompter.accept_move(state, @messages.bad_move)
end
[] ->
parse_input(RandomGuess.new(state), state)
[move] when move in ["all", "set", "stop"] ->
put_in(state.move, [move])
["help"] ->
Prompter.accept_move(state, @messages.help)
[":eof"] ->
parse_input(:eof, state)
[":error" | reason] ->
# E.g. :error 'whatever the reason'
reason = Enum.join(reason, " ")
{reason, []} = Code.eval_string(reason)
parse_input({:error, reason}, state)
_other ->
Prompter.accept_move(state, @messages.bad_move)
end
end
end