mirror of
https://github.com/avitex/elixir-glicko
synced 2024-11-22 03:09:57 +00:00
Add function to calculate draw probability
This commit is contained in:
parent
bb097fc5de
commit
3d5a8e4f89
@ -28,6 +28,13 @@ defmodule Glicko do
|
|||||||
iex> Glicko.win_probability(player, opponent)
|
iex> Glicko.win_probability(player, opponent)
|
||||||
0.5
|
0.5
|
||||||
|
|
||||||
|
Calculate the probability of a player drawing against an opponent.
|
||||||
|
|
||||||
|
iex> player = Player.new_v1
|
||||||
|
iex> opponent = Player.new_v1
|
||||||
|
iex> Glicko.draw_probability(player, opponent)
|
||||||
|
1.0
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
alias __MODULE__.{
|
alias __MODULE__.{
|
||||||
@ -41,7 +48,7 @@ defmodule Glicko do
|
|||||||
@type new_rating_opts :: [system_constant: float, convergence_tolerance: float]
|
@type new_rating_opts :: [system_constant: float, convergence_tolerance: float]
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Calculates the probability of a player winning against an opponent from a player and an opponent.
|
Calculates the probability of a player winning against an opponent.
|
||||||
|
|
||||||
Returns a value between `0.0` and `1.0`.
|
Returns a value between `0.0` and `1.0`.
|
||||||
"""
|
"""
|
||||||
@ -62,6 +69,28 @@ defmodule Glicko do
|
|||||||
calc_e(player_rating, opponent_rating, calc_g(opponent_rating_deviation))
|
calc_e(player_rating, opponent_rating, calc_g(opponent_rating_deviation))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Calculates the probability of a player drawing against an opponent.
|
||||||
|
|
||||||
|
Returns a value between `0.0` and `1.0`.
|
||||||
|
"""
|
||||||
|
@spec draw_probability(player :: Player.t, opponent :: Player.t) :: float
|
||||||
|
def draw_probability(player, opponent) do
|
||||||
|
draw_probability(player |> Player.rating(:v2), opponent |> Player.rating(:v2), opponent |> Player.rating_deviation(:v2))
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Calculates the probability of a player drawing against an opponent from a player rating, opponent rating and opponent rating deviation.
|
||||||
|
|
||||||
|
Values provided for the player rating, opponent rating and opponent rating deviation must be *v2* based.
|
||||||
|
|
||||||
|
Returns a value between `0.0` and `1.0`.
|
||||||
|
"""
|
||||||
|
@spec draw_probability(player_rating :: Player.rating, opponent_rating :: Player.rating, opponent_rating_deviation :: Player.rating_deviation) :: float
|
||||||
|
def draw_probability(player_rating, opponent_rating, opponent_rating_deviation) do
|
||||||
|
1 - abs(win_probability(player_rating, opponent_rating, opponent_rating_deviation) - 0.5) / 0.5
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Generate a new rating from an existing rating and a series (or lack) of results.
|
Generate a new rating from an existing rating and a series (or lack) of results.
|
||||||
|
|
||||||
|
@ -22,29 +22,47 @@ defmodule GlickoTest do
|
|||||||
|
|
||||||
@valid_player_rating_deviation_after_no_results 200.2714 |> Player.scale_rating_deviation_to(:v2)
|
@valid_player_rating_deviation_after_no_results 200.2714 |> Player.scale_rating_deviation_to(:v2)
|
||||||
|
|
||||||
test "new rating (with results)" do
|
describe "new rating" do
|
||||||
player = Glicko.new_rating(@player, @results, [system_constant: 0.5])
|
test "with results" do
|
||||||
|
player = Glicko.new_rating(@player, @results, [system_constant: 0.5])
|
||||||
|
|
||||||
assert_in_delta Player.rating(player), @valid_player_rating_after_results, 1.0e-4
|
assert_in_delta Player.rating(player), @valid_player_rating_after_results, 1.0e-4
|
||||||
assert_in_delta Player.rating_deviation(player), @valid_player_rating_deviation_after_results, 1.0e-4
|
assert_in_delta Player.rating_deviation(player), @valid_player_rating_deviation_after_results, 1.0e-4
|
||||||
assert_in_delta Player.volatility(player), @valid_player_volatility_after_results, 1.0e-5
|
assert_in_delta Player.volatility(player), @valid_player_volatility_after_results, 1.0e-5
|
||||||
|
end
|
||||||
|
|
||||||
|
test "no results" do
|
||||||
|
player = Glicko.new_rating(@player, [])
|
||||||
|
|
||||||
|
assert_in_delta Player.rating_deviation(player), @valid_player_rating_deviation_after_no_results, 1.0e-4
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "new rating (no results)" do
|
describe "win probability" do
|
||||||
player = Glicko.new_rating(@player, [])
|
test "with same ratings" do
|
||||||
|
assert Glicko.win_probability(Player.new_v1, Player.new_v1) == 0.5
|
||||||
|
end
|
||||||
|
|
||||||
assert_in_delta Player.rating_deviation(player), @valid_player_rating_deviation_after_no_results, 1.0e-4
|
test "with better opponent" do
|
||||||
|
assert Glicko.win_probability(Player.new_v1([rating: 1500]), Player.new_v1([rating: 1600])) < 0.5
|
||||||
|
end
|
||||||
|
|
||||||
|
test "with better player" do
|
||||||
|
assert Glicko.win_probability(Player.new_v1([rating: 1600]), Player.new_v1([rating: 1500])) > 0.5
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "win probability with same ratings" do
|
describe "draw probability" do
|
||||||
assert Glicko.win_probability(Player.new_v1, Player.new_v1) == 0.5
|
test "with same ratings" do
|
||||||
end
|
assert Glicko.draw_probability(Player.new_v1, Player.new_v1) == 1
|
||||||
|
end
|
||||||
|
|
||||||
test "win probability with better opponent" do
|
test "with better opponent" do
|
||||||
assert Glicko.win_probability(Player.new_v1([rating: 1500]), Player.new_v1([rating: 1600])) < 0.5
|
assert Glicko.draw_probability(Player.new_v1([rating: 1500]), Player.new_v1([rating: 1600])) < 1
|
||||||
end
|
end
|
||||||
|
|
||||||
test "win probability with better player" do
|
test "with better player" do
|
||||||
assert Glicko.win_probability(Player.new_v1([rating: 1600]), Player.new_v1([rating: 1500])) > 0.5
|
assert Glicko.draw_probability(Player.new_v1([rating: 1600]), Player.new_v1([rating: 1500])) < 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user