# ┌─────────────────────────────────────────────────────────────────┐ # │ Inspired by the course "Elixir for Programmers" by Dave Thomas. │ # └─────────────────────────────────────────────────────────────────┘ defmodule Islands.Client.Player do @moduledoc """ Models a player in the _Game of Islands_. ##### Inspired by the course [Elixir for Programmers](https://codestool.coding-gnome.com/courses/elixir-for-programmers) by Dave Thomas. """ alias Islands.Client.{GameOver, Input, Mover, React, State} alias Islands.Tally @doc """ Reacts to a game state, makes a move and repeats until the game is over. Player1 reacts to game state: - `:initialized` by waiting for game state `:players_set` - `:players_set` by waiting for game state `:player1_turn` - `:player2_turn` by waiting for game state `:player1_turn` or `:game_over` - `:game_over` by exiting the game Player2 reacts to game state: - `:players_set` by waiting for game state `:player2_turn` - `:player1_turn` by waiting for game state `:player2_turn` or `:game_over` - `:game_over` by exiting the game """ # :initialized, :players_set, :player1_turn, :player2_turn, :game_over @spec play(State.t()) :: no_return def play(%State{tally: %Tally{game_state: game_state}} = state) do React.react_to(state, game_state) |> continue() end def play(_error) do self() |> Process.exit(:normal) end ## Private functions @spec continue(State.t()) :: no_return defp continue(%State{tally: %Tally{game_state: :game_over}} = state) do # This player was notified of the `:game_over` game state. # The oppponent player caused the `:game_over` game state. GameOver.exit(state, end_game: false) end defp continue(state) do :ok = Tally.summary(state.tally, state.player_id) state |> Input.accept_move() |> Mover.make_move() |> play() end end