1
0
mirror of https://github.com/avitex/elixir-glicko synced 2025-01-15 10:49:58 +00:00

Compare commits

...

10 Commits

Author SHA1 Message Date
Mikael Muszynski
363b367d4c
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:03:41 +02:00
Mikael Muszynski
9cb997e2c1 Update algorithm to match the latest Glicko-2 documentation
On 2022-03-22, the Glicko-2 algorithm was updated, with the following
line being added to the [Glicko web page][1]:

> This document has been revised on March 22, 2022, to replace a "<"
> with "<=" in item 4(b) of Step 5 (page 3).

See the [Glicko-2 document][2] for details.

Tests for this change are missing, as at the time of writing I couldn't
figure out a test that only made use of the current public interface.

  [1]: http://glicko.net/glicko.html
  [2]: http://glicko.net/glicko/glicko2.pdf
2024-06-10 13:02:23 +02:00
dependabot-preview[bot]
172f8dd8d0 Upgrade to GitHub-native Dependabot 2024-06-10 13:01:50 +02:00
Mikael Muszynski
636d84b4a9 Update dependency "credo" 2024-06-10 13:00:04 +02:00
dependabot-preview[bot]
a1f0c2f337 Bump ex_doc from 0.22.0 to 0.24.2
Bumps [ex_doc](https://github.com/elixir-lang/ex_doc) from 0.22.0 to 0.24.2.
- [Release notes](https://github.com/elixir-lang/ex_doc/releases)
- [Changelog](https://github.com/elixir-lang/ex_doc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/elixir-lang/ex_doc/compare/v0.22.0...v0.24.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2024-06-10 12:45:33 +02:00
Mikael Muszynski
7297ff6318 Create GitHub Actions worflow for Elixir
Auto-generated code by writing choosing a "recommended Elixir
workflow".
2024-06-10 12:42:15 +02:00
dependabot-preview[bot]
b7b60afbe3
Bump ex_doc from 0.21.3 to 0.22.0 (#11)
Bumps [ex_doc](https://github.com/elixir-lang/ex_doc) from 0.21.3 to 0.22.0.
- [Release notes](https://github.com/elixir-lang/ex_doc/releases)
- [Changelog](https://github.com/elixir-lang/ex_doc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/elixir-lang/ex_doc/compare/v0.21.3...v0.22.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-05-12 17:17:11 +10:00
dependabot-preview[bot]
5385b26b65
Bump credo from 1.3.2 to 1.4.0 (#10)
Bumps [credo](https://github.com/rrrene/credo) from 1.3.2 to 1.4.0.
- [Release notes](https://github.com/rrrene/credo/releases)
- [Changelog](https://github.com/rrrene/credo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rrrene/credo/compare/v1.3.2...v1.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-21 15:50:17 +10:00
dependabot-preview[bot]
e89e29a9a9
Bump credo from 0.8.8 to 1.3.2 (#9)
Bumps [credo](https://github.com/rrrene/credo) from 0.8.8 to 1.3.2.
- [Release notes](https://github.com/rrrene/credo/releases)
- [Changelog](https://github.com/rrrene/credo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rrrene/credo/compare/v0.8.8...v1.3.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-21 01:04:59 +10:00
avitex
d48d2b6967
update to travis.com 2020-04-14 18:36:22 +10:00
9 changed files with 196 additions and 101 deletions

17
.github/dependabot.yml vendored Normal file
View 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
View 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

View File

@ -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)

View File

@ -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}

View File

@ -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 players 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,

View File

@ -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

View File

@ -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

View File

@ -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], []},
}

View File

@ -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