Packages
hangman_engine
0.1.36
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.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.31
0.1.30
0.1.29
0.1.28
Models the Hangman Game.
Current section
Files
Jump to
Current section
Files
lib/hangman/engine.ex
# ┌──────────────────────────────────────────────────────────────┐
# │ Based on the course "Elixir for Programmers" by Dave Thomas. │
# └──────────────────────────────────────────────────────────────┘
defmodule Hangman.Engine do
@moduledoc """
Models the _Hangman Game_. Times out after 30 minutes of inactivity.
##### Based on the course [Elixir for Programmers](https://codestool.coding-gnome.com/courses/elixir-for-programmers) by Dave Thomas.
"""
alias __MODULE__.{DynGameSup, GameServer}
alias Hangman.Game
@doc """
Starts a new game server process and supervises it.
## Examples
iex> alias Hangman.Engine
iex> {:ok, game_id} = Engine.new_game("Meg")
iex> {:error, {:already_started, ^game_id}} = Engine.new_game("Meg")
iex> is_pid(game_id)
true
"""
@spec new_game(Game.name()) :: Supervisor.on_start_child()
def new_game(game_name) when is_binary(game_name) do
DynamicSupervisor.start_child(DynGameSup, {GameServer, game_name})
end
@doc """
Stops a game server process normally. It won't be restarted.
## Examples
iex> alias Hangman.Engine
iex> Engine.new_game("Ben")
iex> Engine.end_game("Ben")
:ok
"""
@spec end_game(Game.name()) :: :ok
def end_game(game_name) when is_binary(game_name) do
GameServer.via(game_name) |> GenServer.stop(:shutdown)
end
@doc """
Returns the tally of a game.
## Examples
iex> alias Hangman.Engine
iex> Engine.new_game("Jim")
iex> tally = Engine.tally("Jim")
iex> %{
...> game_state: :initializing,
...> turns_left: 7,
...> letters: letters,
...> guesses: []
...> } = tally
iex> all_underscores? = Enum.all?(letters, & &1 == "_")
iex> is_list(letters) and length(letters) > 0 and all_underscores?
true
"""
@spec tally(Game.name()) :: Game.tally()
def tally(game_name) when is_binary(game_name) do
GameServer.via(game_name) |> GenServer.call(:tally)
end
@doc """
Makes a move by guessing a letter.
## Examples
iex> alias Hangman.Engine
iex> Engine.new_game("Ed")
iex> Engine.make_move("Ed", "a").game_state in [:good_guess, :bad_guess]
true
"""
@spec make_move(Game.name(), Game.letter()) :: Game.tally()
def make_move(game_name, guess)
when is_binary(game_name) and is_binary(guess) do
GameServer.via(game_name) |> GenServer.call({:make_move, guess})
end
end