mirror of
https://github.com/avitex/elixir-glicko
synced 2024-11-24 20:19: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)
|
||||
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__.{
|
||||
@ -41,7 +48,7 @@ defmodule Glicko do
|
||||
@type new_rating_opts :: [system_constant: float, convergence_tolerance: float]
|
||||
|
||||
@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`.
|
||||
"""
|
||||
@ -62,6 +69,28 @@ defmodule Glicko do
|
||||
calc_e(player_rating, opponent_rating, calc_g(opponent_rating_deviation))
|
||||
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 """
|
||||
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)
|
||||
|
||||
test "new rating (with results)" do
|
||||
player = Glicko.new_rating(@player, @results, [system_constant: 0.5])
|
||||
describe "new rating" do
|
||||
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_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.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.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
|
||||
|
||||
test "new rating (no results)" do
|
||||
player = Glicko.new_rating(@player, [])
|
||||
describe "win probability" do
|
||||
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
|
||||
|
||||
test "win probability with same ratings" do
|
||||
assert Glicko.win_probability(Player.new_v1, Player.new_v1) == 0.5
|
||||
end
|
||||
describe "draw probability" do
|
||||
test "with same ratings" do
|
||||
assert Glicko.draw_probability(Player.new_v1, Player.new_v1) == 1
|
||||
end
|
||||
|
||||
test "win probability with better opponent" do
|
||||
assert Glicko.win_probability(Player.new_v1([rating: 1500]), Player.new_v1([rating: 1600])) < 0.5
|
||||
end
|
||||
test "with better opponent" do
|
||||
assert Glicko.draw_probability(Player.new_v1([rating: 1500]), Player.new_v1([rating: 1600])) < 1
|
||||
end
|
||||
|
||||
test "win probability with better player" do
|
||||
assert Glicko.win_probability(Player.new_v1([rating: 1600]), Player.new_v1([rating: 1500])) > 0.5
|
||||
test "with better player" do
|
||||
assert Glicko.draw_probability(Player.new_v1([rating: 1600]), Player.new_v1([rating: 1500])) < 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user