1
0
mirror of https://github.com/avitex/elixir-glicko synced 2024-09-21 15:19:57 +00:00
glicko-elixir/lib/glicko/result.ex
Mikael Muszynski c1089996d3 Convert Player (v1/v2) and Result to structs
In an effort to give names to core concepts in the library, replace the
current way of passing around tuples (of varying length and content)
with appropriately named structs.

In the interest of keeping the patch focused: primarily replace internal
implementation of the added struct modules, and keep the interfaces for
creation, conversion (player v1 to v2, and vice versa), and field access
as they currently are.
2024-06-10 13:04:45 +02:00

81 lines
2.6 KiB
Elixir

defmodule Glicko.Result do
@moduledoc """
Provides convenience functions for handling a result against an opponent.
## Usage
iex> opponent = Player.new_v2
iex> Result.new(opponent, 1.0)
%Result{opponent_rating: 0.0, opponent_rating_deviation: 2.014761872416068, score: 1.0}
iex> Result.new(opponent, :draw) # With shortcut
%Result{opponent_rating: 0.0, opponent_rating_deviation: 2.014761872416068, score: 0.5}
"""
alias Glicko.Player
@type t :: %__MODULE__{
opponent_rating: Player.rating(),
opponent_rating_deviation: Player.rating_deviation(),
score: score
}
@type score :: float
@type score_shortcut :: :loss | :draw | :win
@score_shortcut_map %{loss: 0.0, draw: 0.5, win: 1.0}
@score_shortcuts Map.keys(@score_shortcut_map)
defstruct [:opponent_rating, :opponent_rating_deviation, :score]
@doc """
Creates a new result from an opponent rating, opponent rating deviation and score.
Values provided for the opponent rating and opponent rating deviation must be *v2* based.
Supports passing either `:loss`, `:draw`, or `:win` as shortcuts.
"""
@spec new(Player.rating(), Player.rating_deviation(), score | score_shortcut) :: t
def new(opponent_rating, opponent_rating_deviation, score) when is_number(score) do
%__MODULE__{
opponent_rating: opponent_rating,
opponent_rating_deviation: opponent_rating_deviation,
score: score
}
end
def new(opponent_rating, opponent_rating_deviation, score_type)
when is_atom(score_type) and score_type in @score_shortcuts do
score = Map.fetch!(@score_shortcut_map, score_type)
new(opponent_rating, opponent_rating_deviation, score)
end
@doc """
Creates a new result from an opponent and score.
Supports passing either `:loss`, `:draw`, or `:win` as shortcuts.
"""
@spec new(opponent :: Player.t(), score :: score | score_shortcut) :: t
def new(opponent, score) do
new(Player.rating(opponent, :v2), Player.rating_deviation(opponent, :v2), score)
end
@doc """
Convenience function for accessing an opponent's rating.
"""
@spec opponent_rating(result :: t()) :: Player.rating()
def opponent_rating(%__MODULE__{} = result), do: result.opponent_rating
@doc """
Convenience function for accessing an opponent's rating deviation.
"""
@spec opponent_rating_deviation(result :: t()) :: Player.rating_deviation()
def opponent_rating_deviation(%__MODULE__{} = result), do: result.opponent_rating_deviation
@doc """
Convenience function for accessing the score.
"""
@spec score(result :: t()) :: score
def score(%__MODULE__{} = result), do: result.score
end