defmodule Hangman.Text.Client.Prompter do @moduledoc """ Prompts a player for a move. """ alias Hangman.Text.Client.{Player, State} @doc """ Accepts a player's move. """ @spec accept_move(State.t()) :: State.t() | no_return def accept_move(%State{} = state) do "Your guess (or stop): " |> IO.gets() |> check_input(state) end ## Private functions # "Player's input" @typep input :: String.t() | {:error, atom} | :eof @spec check_input(input, State.t()) :: State.t() | no_return defp check_input({:error, reason}, state), do: Player.end_game(state, "Game ended: #{inspect(reason)}.") defp check_input(:eof, state), do: Player.end_game(state, "Looks like you gave up somehow.") defp check_input(input, state) do case String.trim(input) do "stop" -> Player.end_game(state, "Looks like you gave up.") <> = guess when char in ?a..?z -> put_in(state.guess, guess) _bad_input -> IO.puts("Please enter a single lowercase letter.\n") accept_move(state) end end end