Packages
hangman_text_client
0.1.63
0.1.87
0.1.86
0.1.85
0.1.84
0.1.83
0.1.82
0.1.81
0.1.80
0.1.79
0.1.78
0.1.77
0.1.76
0.1.75
0.1.74
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
Text client for the Hangman Game.
Current section
Files
Jump to
Current section
Files
lib/hangman/text/client/player.ex
defmodule Hangman.Text.Client.Player do
@moduledoc """
Plays a game until it is won, lost or stopped.
"""
alias IO.ANSI.Plus, as: ANSI
alias Hangman.{Game, Engine}
alias Hangman.Text.Client.{Mover, Prompter, State, Summary}
@alphabet Enum.map(?a..?z, &<<&1>>)
@doc """
Plays a game until it is won, lost or stopped.
"""
# won, lost, good guess, bad guess, already used, initializing...
@spec play(State.t()) :: no_return
def play(%State{tally: %{game_state: :won}} = state),
do: end_game(state, [:light_cyan, "Bravo, you WON!"])
def play(%State{tally: %{game_state: :lost}} = state),
do: end_game(state, [:light_magenta, "Sorry, you lost."])
def play(%State{tally: %{game_state: :good_guess}} = state),
do: continue(state, [:light_green, "Good guess!"])
def play(%State{tally: %{game_state: :bad_guess}} = state),
do: continue(state, [:light_red, "Bad guess..."])
def play(%State{tally: %{game_state: :already_used}} = state),
do: continue(state, [:light_yellow, "Already used..."])
# initializing
def play(%State{} = state), do: continue(state)
@doc """
Displays a `message` and ends the game normally.
"""
@spec end_game(State.t(), ANSI.ansidata()) :: no_return
def end_game(%State{tally: tally, game_name: game_name}, message) do
ANSI.puts(message)
%{letters: letters} = win_lose(tally, game_name)
["\nWord was: ", :light_cyan, " #{Enum.join(letters, " ")}"] |> ANSI.puts()
Engine.end_game(game_name)
self() |> Process.exit(:normal)
end
## Private functions
@spec continue(State.t(), ANSI.ansilist()) :: no_return
defp continue(state, message \\ []) do
unless Enum.empty?(message), do: ANSI.puts(message)
state
|> Summary.display()
|> Prompter.accept_move()
|> Mover.make_move()
|> play()
end
@spec win_lose(Game.tally(), Game.name()) :: Game.tally()
defp win_lose(%{game_state: game_state} = tally, _game_name)
when game_state in [:won, :lost],
do: tally
defp win_lose(%{guesses: guesses}, game_name) do
[guess | _] = @alphabet -- guesses
Engine.make_move(game_name, guess) |> win_lose(game_name)
end
end