mirror of
https://github.com/avitex/elixir-glicko
synced 2025-01-15 10:49:58 +00:00
Compare commits
10 Commits
721ddbef2b
...
363b367d4c
Author | SHA1 | Date | |
---|---|---|---|
|
363b367d4c | ||
|
9cb997e2c1 | ||
|
172f8dd8d0 | ||
|
636d84b4a9 | ||
|
a1f0c2f337 | ||
|
7297ff6318 | ||
|
b7b60afbe3 | ||
|
5385b26b65 | ||
|
e89e29a9a9 | ||
|
d48d2b6967 |
17
.github/dependabot.yml
vendored
Normal file
17
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: mix
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "19:30"
|
||||
open-pull-requests-limit: 10
|
||||
ignore:
|
||||
- dependency-name: ex_doc
|
||||
versions:
|
||||
- 0.23.0
|
||||
- 0.24.0
|
||||
- 0.24.1
|
||||
- dependency-name: credo
|
||||
versions:
|
||||
- 1.5.4
|
38
.github/workflows/elixir.yml
vendored
Normal file
38
.github/workflows/elixir.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
|
||||
name: Elixir CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and test
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Elixir
|
||||
uses: erlef/setup-beam@61e01a43a562a89bfc54c7f9a378ff67b03e4a21 # v1.16.0
|
||||
with:
|
||||
elixir-version: '1.15.2' # [Required] Define the Elixir version
|
||||
otp-version: '26.0' # [Required] Define the Erlang/OTP version
|
||||
- name: Restore dependencies cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: deps
|
||||
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
|
||||
restore-keys: ${{ runner.os }}-mix-
|
||||
- name: Install dependencies
|
||||
run: mix deps.get
|
||||
- name: Run tests
|
||||
run: mix test
|
@ -1,4 +1,4 @@
|
||||
[![Build Status](https://travis-ci.org/avitex/elixir-glicko.svg)](https://travis-ci.org/avitex/elixir-glicko)
|
||||
[![Build Status](https://travis-ci.com/avitex/elixir-glicko.svg?branch=master)](https://travis-ci.com/avitex/elixir-glicko)
|
||||
[![Hex.pm](https://img.shields.io/hexpm/v/glicko.svg)](https://hex.pm/packages/glicko)
|
||||
[![Hex Docs](https://img.shields.io/badge/hex-docs-blue.svg)](https://hexdocs.pm/glicko)
|
||||
[![Inline docs](http://inch-ci.org/github/avitex/elixir-glicko.svg)](http://inch-ci.org/github/avitex/elixir-glicko)
|
||||
|
@ -13,13 +13,13 @@ defmodule Glicko do
|
||||
...> Result.new(Player.new_v1([rating: 1700, rating_deviation: 300]), :loss)]
|
||||
iex> player = Player.new_v1([rating: 1500, rating_deviation: 200])
|
||||
iex> Glicko.new_rating(player, results, [system_constant: 0.5])
|
||||
{1464.0506705393013, 151.51652412385727}
|
||||
%Player.V1{rating: 1464.0506705393013, rating_deviation: 151.51652412385727}
|
||||
|
||||
Get a player's new rating when they haven't played within a rating period.
|
||||
|
||||
iex> player = Player.new_v1([rating: 1500, rating_deviation: 200])
|
||||
iex> Glicko.new_rating(player, [], [system_constant: 0.5])
|
||||
{1.5e3, 200.27141669877065}
|
||||
%Player.V1{rating: 1.5e3, rating_deviation: 200.27141669877065}
|
||||
|
||||
Calculate the probability of a player winning against an opponent.
|
||||
|
||||
@ -117,24 +117,33 @@ defmodule Glicko do
|
||||
Player.t()
|
||||
def new_rating(player, results, opts \\ [])
|
||||
|
||||
def new_rating(player, results, opts) when tuple_size(player) == 3 do
|
||||
def new_rating(%Player.V2{} = player, results, opts) do
|
||||
do_new_rating(player, results, opts)
|
||||
end
|
||||
|
||||
def new_rating(player, results, opts) when tuple_size(player) == 2 do
|
||||
def new_rating(%Player.V1{} = player, results, opts) do
|
||||
player
|
||||
|> Player.to_v2()
|
||||
|> do_new_rating(results, opts)
|
||||
|> Player.to_v1()
|
||||
end
|
||||
|
||||
defp do_new_rating({player_r, player_pre_rd, player_v}, [], _) do
|
||||
player_post_rd = calc_player_post_base_rd(:math.pow(player_pre_rd, 2), player_v)
|
||||
defp do_new_rating(%Player.V2{} = player, [], _) do
|
||||
player_post_rd =
|
||||
calc_player_post_base_rd(:math.pow(player.rating_deviation, 2), player.volatility)
|
||||
|
||||
{player_r, player_post_rd, player_v}
|
||||
%{player | rating_deviation: player_post_rd}
|
||||
end
|
||||
|
||||
defp do_new_rating({player_pre_r, player_pre_rd, player_pre_v}, results, opts) do
|
||||
defp do_new_rating(
|
||||
%Player.V2{
|
||||
rating: player_pre_r,
|
||||
rating_deviation: player_pre_rd,
|
||||
volatility: player_pre_v
|
||||
},
|
||||
results,
|
||||
opts
|
||||
) do
|
||||
sys_const = Keyword.get(opts, :system_constant, @default_system_constant)
|
||||
conv_tol = Keyword.get(opts, :convergence_tolerance, @default_convergence_tolerance)
|
||||
|
||||
@ -184,7 +193,11 @@ defmodule Glicko do
|
||||
player_post_rd = calc_new_player_rating_deviation(player_post_base_rd, variance_est)
|
||||
player_post_r = calc_new_player_rating(results_effect, player_pre_r, player_post_rd)
|
||||
|
||||
{player_post_r, player_post_rd, player_post_v}
|
||||
%Player.V2{
|
||||
rating: player_post_r,
|
||||
rating_deviation: player_post_rd,
|
||||
volatility: player_post_v
|
||||
}
|
||||
end
|
||||
|
||||
defp result_calculations(results, player_pre_r) do
|
||||
@ -268,7 +281,7 @@ defmodule Glicko do
|
||||
fc = calc_f(alpha, delta, player_pre_rd_sq, variance_est, sys_const, c)
|
||||
|
||||
{a, fa} =
|
||||
if fc * fb < 0 do
|
||||
if fc * fb <= 0 do
|
||||
{b, fb}
|
||||
else
|
||||
{a, fa / 2}
|
||||
|
@ -7,27 +7,27 @@ defmodule Glicko.Player do
|
||||
Create a *v1* player with the default values for an unrated player.
|
||||
|
||||
iex> Player.new_v1
|
||||
{1.5e3, 350.0}
|
||||
%Player.V1{rating: 1.5e3, rating_deviation: 350.0}
|
||||
|
||||
Create a *v2* player with the default values for an unrated player.
|
||||
|
||||
iex> Player.new_v2
|
||||
{0.0, 2.014761872416068, 0.06}
|
||||
%Player.V2{rating: 0.0, rating_deviation: 2.014761872416068, volatility: 0.06}
|
||||
|
||||
Create a player with custom values.
|
||||
|
||||
iex> Player.new_v2([rating: 3.0, rating_deviation: 2.0, volatility: 0.05])
|
||||
{3.0, 2.0, 0.05}
|
||||
iex> Player.new_v2(rating: 3.0, rating_deviation: 2.0, volatility: 0.05)
|
||||
%Player.V2{rating: 3.0, rating_deviation: 2.0, volatility: 0.05}
|
||||
|
||||
Convert a *v2* player to a *v1*. Note this drops the volatility.
|
||||
|
||||
iex> Player.new_v2 |> Player.to_v1
|
||||
{1.5e3, 350.0}
|
||||
%Player.V1{rating: 1.5e3, rating_deviation: 350.0}
|
||||
|
||||
Convert a *v1* player to a *v2*.
|
||||
|
||||
iex> Player.new_v1 |> Player.to_v2(0.06)
|
||||
{0.0, 2.014761872416068, 0.06}
|
||||
%Player.V2{rating: 0.0, rating_deviation: 2.014761872416068, volatility: 0.06}
|
||||
|
||||
Note calling `to_v1` with a *v1* player or likewise with `to_v2` and a *v2* player
|
||||
will pass-through unchanged. The volatility arg in this case is ignored.
|
||||
@ -38,39 +38,54 @@ defmodule Glicko.Player do
|
||||
|
||||
"""
|
||||
|
||||
defmodule V1 do
|
||||
@initial_rating 1500.0
|
||||
@initial_rating_deviation 350.0
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
rating: float(),
|
||||
rating_deviation: float()
|
||||
}
|
||||
|
||||
defstruct rating: @initial_rating,
|
||||
rating_deviation: @initial_rating_deviation
|
||||
end
|
||||
|
||||
defmodule V2 do
|
||||
@magic_version_scale 173.7178
|
||||
@magic_version_scale_rating 1500.0
|
||||
|
||||
@v1_initial_rating 1500.0
|
||||
@v1_initial_rating_deviation 350.0
|
||||
|
||||
@initial_rating (@v1_initial_rating - @magic_version_scale_rating) / @magic_version_scale
|
||||
@initial_rating_deviation @v1_initial_rating_deviation / @magic_version_scale
|
||||
@initial_volatility 0.06
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
rating: float(),
|
||||
rating_deviation: float(),
|
||||
volatility: float()
|
||||
}
|
||||
|
||||
defstruct rating: @initial_rating,
|
||||
rating_deviation: @initial_rating_deviation,
|
||||
volatility: @initial_volatility
|
||||
end
|
||||
|
||||
@magic_version_scale 173.7178
|
||||
@magic_version_scale_rating 1500.0
|
||||
|
||||
@type t :: v1 | v2
|
||||
|
||||
@type v1 :: {rating, rating_deviation}
|
||||
@type v2 :: {rating, rating_deviation, volatility}
|
||||
@type v1 :: V1.t()
|
||||
@type v2 :: V2.t()
|
||||
|
||||
@type version :: :v1 | :v2
|
||||
@type rating :: float
|
||||
@type rating_deviation :: float
|
||||
@type volatility :: float
|
||||
|
||||
@doc """
|
||||
The recommended initial rating value for a new player.
|
||||
"""
|
||||
@spec initial_rating(version) :: rating
|
||||
def initial_rating(_version = :v1), do: 1500.0
|
||||
|
||||
def initial_rating(_version = :v2) do
|
||||
:v1 |> initial_rating |> scale_rating_to(:v2)
|
||||
end
|
||||
|
||||
@doc """
|
||||
The recommended initial rating deviation value for a new player.
|
||||
"""
|
||||
@spec initial_rating_deviation(version) :: rating_deviation
|
||||
def initial_rating_deviation(_version = :v1), do: 350.0
|
||||
|
||||
def initial_rating_deviation(_version = :v2) do
|
||||
:v1 |> initial_rating_deviation |> scale_rating_deviation_to(:v2)
|
||||
end
|
||||
|
||||
@doc """
|
||||
The recommended initial volatility value for a new player.
|
||||
"""
|
||||
@ -84,10 +99,7 @@ defmodule Glicko.Player do
|
||||
"""
|
||||
@spec new_v1(rating: rating, rating_deviation: rating_deviation) :: v1
|
||||
def new_v1(opts \\ []) when is_list(opts) do
|
||||
{
|
||||
Keyword.get(opts, :rating, initial_rating(:v1)),
|
||||
Keyword.get(opts, :rating_deviation, initial_rating_deviation(:v1))
|
||||
}
|
||||
struct(V1, opts)
|
||||
end
|
||||
|
||||
@doc """
|
||||
@ -97,11 +109,7 @@ defmodule Glicko.Player do
|
||||
"""
|
||||
@spec new_v2(rating: rating, rating_deviation: rating_deviation, volatility: volatility) :: v2
|
||||
def new_v2(opts \\ []) when is_list(opts) do
|
||||
{
|
||||
Keyword.get(opts, :rating, initial_rating(:v2)),
|
||||
Keyword.get(opts, :rating_deviation, initial_rating_deviation(:v2)),
|
||||
Keyword.get(opts, :volatility, initial_volatility())
|
||||
}
|
||||
struct(V2, opts)
|
||||
end
|
||||
|
||||
@doc """
|
||||
@ -112,12 +120,12 @@ defmodule Glicko.Player do
|
||||
Note the volatility field used in a v2 player will be lost in the conversion.
|
||||
"""
|
||||
@spec to_v1(player :: t) :: v1
|
||||
def to_v1({rating, rating_deviation}), do: {rating, rating_deviation}
|
||||
def to_v1(%V1{} = player), do: player
|
||||
|
||||
def to_v1({rating, rating_deviation, _}) do
|
||||
{
|
||||
rating |> scale_rating_to(:v1),
|
||||
rating_deviation |> scale_rating_deviation_to(:v1)
|
||||
def to_v1(%V2{rating: rating, rating_deviation: rating_deviation}) do
|
||||
%V1{
|
||||
rating: scale_rating_to(rating, :v1),
|
||||
rating_deviation: scale_rating_deviation_to(rating_deviation, :v1)
|
||||
}
|
||||
end
|
||||
|
||||
@ -129,53 +137,52 @@ defmodule Glicko.Player do
|
||||
@spec to_v2(player :: t, volatility :: volatility) :: v2
|
||||
def to_v2(player, volatility \\ initial_volatility())
|
||||
|
||||
def to_v2({rating, rating_deviation, volatility}, _volatility),
|
||||
do: {rating, rating_deviation, volatility}
|
||||
|
||||
def to_v2({rating, rating_deviation}, volatility) do
|
||||
{
|
||||
rating |> scale_rating_to(:v2),
|
||||
rating_deviation |> scale_rating_deviation_to(:v2),
|
||||
volatility
|
||||
def to_v2(%V1{rating: rating, rating_deviation: rating_deviation}, volatility) do
|
||||
%V2{
|
||||
rating: scale_rating_to(rating, :v2),
|
||||
rating_deviation: scale_rating_deviation_to(rating_deviation, :v2),
|
||||
volatility: volatility
|
||||
}
|
||||
end
|
||||
|
||||
def to_v2(%V2{} = player, _volatility) do
|
||||
player
|
||||
end
|
||||
|
||||
@doc """
|
||||
A version agnostic method for getting a player's rating.
|
||||
"""
|
||||
@spec rating(player :: t, as_version :: version | nil) :: rating
|
||||
def rating(player, as_version \\ nil)
|
||||
def rating({rating, _}, nil), do: rating
|
||||
def rating({rating, _, _}, nil), do: rating
|
||||
def rating({rating, _}, :v1), do: rating
|
||||
def rating({rating, _}, :v2), do: rating |> scale_rating_to(:v2)
|
||||
def rating({rating, _, _}, :v1), do: rating |> scale_rating_to(:v1)
|
||||
def rating({rating, _, _}, :v2), do: rating
|
||||
def rating(%_{rating: rating}, nil), do: rating
|
||||
def rating(%V1{rating: rating}, :v1), do: rating
|
||||
def rating(%V2{rating: rating}, :v2), do: rating
|
||||
def rating(%V1{rating: rating}, :v2), do: rating |> scale_rating_to(:v2)
|
||||
def rating(%V2{rating: rating}, :v1), do: rating |> scale_rating_to(:v1)
|
||||
|
||||
@doc """
|
||||
A version agnostic method for getting a player's rating deviation.
|
||||
"""
|
||||
@spec rating_deviation(player :: t, as_version :: version | nil) :: rating_deviation
|
||||
def rating_deviation(player, as_version \\ nil)
|
||||
def rating_deviation({_, rating_deviation}, nil), do: rating_deviation
|
||||
def rating_deviation({_, rating_deviation, _}, nil), do: rating_deviation
|
||||
def rating_deviation({_, rating_deviation}, :v1), do: rating_deviation
|
||||
def rating_deviation(%V1{rating_deviation: rating_deviation}, nil), do: rating_deviation
|
||||
def rating_deviation(%V2{rating_deviation: rating_deviation}, nil), do: rating_deviation
|
||||
def rating_deviation(%V1{rating_deviation: rating_deviation}, :v1), do: rating_deviation
|
||||
def rating_deviation(%V2{rating_deviation: rating_deviation}, :v2), do: rating_deviation
|
||||
|
||||
def rating_deviation({_, rating_deviation}, :v2),
|
||||
def rating_deviation(%V1{rating_deviation: rating_deviation}, :v2),
|
||||
do: rating_deviation |> scale_rating_deviation_to(:v2)
|
||||
|
||||
def rating_deviation({_, rating_deviation, _}, :v1),
|
||||
def rating_deviation(%V2{rating_deviation: rating_deviation}, :v1),
|
||||
do: rating_deviation |> scale_rating_deviation_to(:v1)
|
||||
|
||||
def rating_deviation({_, rating_deviation, _}, :v2), do: rating_deviation
|
||||
|
||||
@doc """
|
||||
A version agnostic method for getting a player's volatility.
|
||||
"""
|
||||
@spec volatility(player :: t, default_volatility :: volatility) :: volatility
|
||||
def volatility(player, default_volatility \\ initial_volatility())
|
||||
def volatility({_, _}, default_volatility), do: default_volatility
|
||||
def volatility({_, _, volatility}, _), do: volatility
|
||||
def volatility(%V1{}, default_volatility), do: default_volatility
|
||||
def volatility(%V2{volatility: volatility}, _), do: volatility
|
||||
|
||||
@doc """
|
||||
A convenience function for summarizing a player's strength as a 95%
|
||||
@ -192,7 +199,8 @@ defmodule Glicko.Player do
|
||||
When a player has a low RD, the interval would be narrow, so that we would
|
||||
be 95% confident about a player’s strength being in a small interval of values.
|
||||
"""
|
||||
@spec rating_interval(player :: t, as_version :: version | nil) :: {rating_low :: float, rating_high :: float}
|
||||
@spec rating_interval(player :: t, as_version :: version | nil) ::
|
||||
{rating_low :: float, rating_high :: float}
|
||||
def rating_interval(player, as_version \\ nil) do
|
||||
{
|
||||
rating(player, as_version) - rating_deviation(player, as_version) * 2,
|
||||
|
@ -6,15 +6,19 @@ defmodule Glicko.Result do
|
||||
|
||||
iex> opponent = Player.new_v2
|
||||
iex> Result.new(opponent, 1.0)
|
||||
{0.0, 2.014761872416068, 1.0}
|
||||
%Result{opponent_rating: 0.0, opponent_rating_deviation: 2.014761872416068, score: 1.0}
|
||||
iex> Result.new(opponent, :draw) # With shortcut
|
||||
{0.0, 2.014761872416068, 0.5}
|
||||
%Result{opponent_rating: 0.0, opponent_rating_deviation: 2.014761872416068, score: 0.5}
|
||||
|
||||
"""
|
||||
|
||||
alias Glicko.Player
|
||||
|
||||
@type t :: {Player.rating(), Player.rating_deviation(), score}
|
||||
@type t :: %__MODULE__{
|
||||
opponent_rating: Player.rating(),
|
||||
opponent_rating_deviation: Player.rating_deviation(),
|
||||
score: score
|
||||
}
|
||||
|
||||
@type score :: float
|
||||
@type score_shortcut :: :loss | :draw | :win
|
||||
@ -22,6 +26,8 @@ defmodule Glicko.Result do
|
||||
@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.
|
||||
|
||||
@ -31,12 +37,17 @@ defmodule Glicko.Result do
|
||||
"""
|
||||
@spec new(Player.rating(), Player.rating_deviation(), score | score_shortcut) :: t
|
||||
def new(opponent_rating, opponent_rating_deviation, score) when is_number(score) do
|
||||
{opponent_rating, opponent_rating_deviation, score}
|
||||
%__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
|
||||
{opponent_rating, opponent_rating_deviation, Map.fetch!(@score_shortcut_map, score_type)}
|
||||
score = Map.fetch!(@score_shortcut_map, score_type)
|
||||
new(opponent_rating, opponent_rating_deviation, score)
|
||||
end
|
||||
|
||||
@doc """
|
||||
@ -53,17 +64,17 @@ defmodule Glicko.Result do
|
||||
Convenience function for accessing an opponent's rating.
|
||||
"""
|
||||
@spec opponent_rating(result :: t()) :: Player.rating()
|
||||
def opponent_rating(_result = {rating, _, _}), do: 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(_result = {_, rating_deviation, _}), do: 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(_result = {_, _, score}), do: score
|
||||
def score(%__MODULE__{} = result), do: result.score
|
||||
end
|
||||
|
2
mix.exs
2
mix.exs
@ -21,7 +21,7 @@ defmodule Glicko.Mixfile do
|
||||
[
|
||||
{:inch_ex, "~> 2.0", only: [:dev, :docs]},
|
||||
{:ex_doc, "~> 0.21", only: :dev, runtime: false},
|
||||
{:credo, "~> 0.8", only: [:dev, :test], runtime: false}
|
||||
{:credo, "~> 1.3", only: [:dev, :test], runtime: false}
|
||||
]
|
||||
end
|
||||
|
||||
|
21
mix.lock
21
mix.lock
@ -1,12 +1,15 @@
|
||||
%{
|
||||
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], []},
|
||||
"credo": {:hex, :credo, "0.8.8", "990e7844a8d06ebacd88744a55853a83b74270b8a8461c55a4d0334b8e1736c9", [:mix], [{:bunt, "~> 0.2.0", [repo: "hexpm", hex: :bunt, optional: false]}], "hexpm"},
|
||||
"earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm"},
|
||||
"ex_doc": {:hex, :ex_doc, "0.21.3", "857ec876b35a587c5d9148a2512e952e24c24345552259464b98bfbb883c7b42", [:mix], [{:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"inch_ex": {:hex, :inch_ex, "2.0.0", "24268a9284a1751f2ceda569cd978e1fa394c977c45c331bb52a405de544f4de", [:mix], [{:bunt, "~> 0.2", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"nimble_parsec": {:hex, :nimble_parsec, "0.5.3", "def21c10a9ed70ce22754fdeea0810dafd53c2db3219a0cd54cf5526377af1c6", [:mix], [], "hexpm"},
|
||||
"bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"},
|
||||
"credo": {:hex, :credo, "1.7.6", "b8f14011a5443f2839b04def0b252300842ce7388f3af177157c86da18dfbeea", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "146f347fb9f8cbc5f7e39e3f22f70acbef51d441baa6d10169dd604bfbc55296"},
|
||||
"earmark": {:hex, :earmark, "1.4.4", "4821b8d05cda507189d51f2caeef370cf1e18ca5d7dfb7d31e9cafe6688106a4", [:mix], [], "hexpm", "1f93aba7340574847c0f609da787f0d79efcab51b044bb6e242cae5aca9d264d"},
|
||||
"earmark_parser": {:hex, :earmark_parser, "1.4.12", "b245e875ec0a311a342320da0551da407d9d2b65d98f7a9597ae078615af3449", [:mix], [], "hexpm", "711e2cc4d64abb7d566d43f54b78f7dc129308a63bc103fbd88550d2174b3160"},
|
||||
"ex_doc": {:hex, :ex_doc, "0.24.2", "e4c26603830c1a2286dae45f4412a4d1980e1e89dc779fcd0181ed1d5a05c8d9", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "e134e1d9e821b8d9e4244687fb2ace58d479b67b282de5158333b0d57c6fb7da"},
|
||||
"file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"},
|
||||
"inch_ex": {:hex, :inch_ex, "2.0.0", "24268a9284a1751f2ceda569cd978e1fa394c977c45c331bb52a405de544f4de", [:mix], [{:bunt, "~> 0.2", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "96d0ec5ecac8cf63142d02f16b7ab7152cf0f0f1a185a80161b758383c9399a8"},
|
||||
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
|
||||
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
|
||||
"makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"},
|
||||
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
|
||||
"nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
|
||||
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], []},
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ defmodule Glicko.PlayerTest do
|
||||
|
||||
doctest Player
|
||||
|
||||
@valid_v1_base {1.0, 2.0}
|
||||
@valid_v2_base {1.0, 2.0, 3.0}
|
||||
@valid_v1_base %Player.V1{rating: 1.0, rating_deviation: 2.0}
|
||||
@valid_v2_base %Player.V2{rating: 1.0, rating_deviation: 2.0, volatility: 3.0}
|
||||
|
||||
test "create v1" do
|
||||
assert @valid_v1_base == Player.new_v1(rating: 1.0, rating_deviation: 2.0)
|
||||
@ -17,13 +17,18 @@ defmodule Glicko.PlayerTest do
|
||||
end
|
||||
|
||||
test "convert player v1 -> v2" do
|
||||
assert {Player.scale_rating_to(1.0, :v2), Player.scale_rating_deviation_to(2.0, :v2), 3.0} ==
|
||||
Player.to_v2(@valid_v1_base, 3.0)
|
||||
assert Player.new_v2(
|
||||
rating: Player.scale_rating_to(1.0, :v2),
|
||||
rating_deviation: Player.scale_rating_deviation_to(2.0, :v2),
|
||||
volatility: 3.0
|
||||
) == Player.to_v2(@valid_v1_base, 3.0)
|
||||
end
|
||||
|
||||
test "convert player v2 -> v1" do
|
||||
assert {Player.scale_rating_to(1.0, :v1), Player.scale_rating_deviation_to(2.0, :v1)} ==
|
||||
Player.to_v1(@valid_v2_base)
|
||||
assert Player.new_v1(
|
||||
rating: Player.scale_rating_to(1.0, :v1),
|
||||
rating_deviation: Player.scale_rating_deviation_to(2.0, :v1)
|
||||
) == Player.to_v1(@valid_v2_base)
|
||||
end
|
||||
|
||||
test "convert player v1 -> v1" do
|
||||
|
Loading…
Reference in New Issue
Block a user