Current section

Files

Jump to
islands_score lib islands score.ex
Raw

lib/islands/score.ex

# ┌───────────────────────────────────────────────────────────────────────┐
# │ Inspired by the book "Functional Web Development" by Lance Halvorsen. │
# └───────────────────────────────────────────────────────────────────────┘
defmodule Islands.Score do
@moduledoc """
Creates a `score` struct for the _Game of Islands_.
##### Inspired by the book [Functional Web Development](https://pragprog.com/book/lhelph/functional-web-development-with-elixir-otp-and-phoenix) by Lance Halvorsen.
"""
alias __MODULE__
alias Islands.{Board, Game, Island, Player, PlayerID}
@player_ids [:player1, :player2]
@derive [Poison.Encoder]
@derive Jason.Encoder
@enforce_keys [:name, :gender, :hits, :misses, :forested_types]
defstruct [:name, :gender, :hits, :misses, :forested_types]
@type t :: %Score{
name: String.t(),
gender: Player.gender(),
hits: non_neg_integer,
misses: non_neg_integer,
forested_types: [Island.type()]
}
@spec board_score(Game.t(), PlayerID.t()) :: t
def board_score(%Game{} = game, player_id) when player_id in @player_ids do
player = game[player_id]
board = player.board
new(player, board)
end
@spec guesses_score(Game.t(), PlayerID.t()) :: t
def guesses_score(%Game{} = game, player_id) when player_id in @player_ids do
opponent = game[Game.opponent_id(player_id)]
board = opponent.board
new(opponent, board)
end
## Private functions
@spec new(Player.t(), Board.t() | nil) :: t
defp new(player, nil) do
%Score{
name: player.name,
gender: player.gender,
hits: 0,
misses: 0,
forested_types: []
}
end
defp new(player, board) do
%Score{
name: player.name,
gender: player.gender,
hits: Board.hits(board),
misses: Board.misses(board),
forested_types: Board.forested_types(board)
}
end
end