Handle players that have not played during the rating period

This commit is contained in:
avitex 2017-11-16 14:19:44 +11:00
parent 218ac020fe
commit b8b5b27e2e
2 changed files with 22 additions and 6 deletions

View File

@ -26,7 +26,15 @@ defmodule Glicko do
do_new_rating(player, results, opts)
end
defp do_new_rating(player = %Player{version: :v2}, results, opts) do
defp do_new_rating(player, [], _) do
player_post_rating_deviation =
Map.new
|> Map.put(:player_rating_deviation_squared, :math.pow(player.rating_deviation, 2))
|> calc_player_pre_rating_deviation(player.volatility)
%{player | rating_deviation: player_post_rating_deviation}
end
defp do_new_rating(player, results, opts) do
results = Enum.map(results, fn result ->
opponent = Player.to_v2(result.opponent)
@ -68,7 +76,7 @@ defmodule Glicko do
# Step 5.5
ctx = Map.put(ctx, :new_player_volatility, calc_new_player_volatility(ctx))
# Step 6
ctx = Map.put(ctx, :prerating_period, calc_prerating_period(ctx))
ctx = Map.put(ctx, :player_pre_rating_deviation, calc_player_pre_rating_deviation(ctx, ctx.new_player_volatility))
# Step 7
ctx = Map.put(ctx, :new_player_rating_deviation, calc_new_player_rating_deviation(ctx))
ctx = Map.put(ctx, :new_player_rating, calc_new_player_rating(ctx))
@ -119,11 +127,11 @@ defmodule Glicko do
end
defp calc_new_player_rating_deviation(ctx) do
1 / :math.sqrt(1 / :math.pow(ctx.prerating_period, 2) + 1 / ctx.variance_estimate)
1 / :math.sqrt(1 / :math.pow(ctx.player_pre_rating_deviation, 2) + 1 / ctx.variance_estimate)
end
defp calc_prerating_period(ctx) do
:math.sqrt((:math.pow(ctx.new_player_volatility, 2) + ctx.player_rating_deviation_squared))
defp calc_player_pre_rating_deviation(ctx, player_volatility) do
:math.sqrt((:math.pow(player_volatility, 2) + ctx.player_rating_deviation_squared))
end
defp iterative_algorithm_initial(ctx) do

View File

@ -20,7 +20,9 @@ defmodule GlickoTest do
@valid_player_rating_deviation_after_results 151.52 |> Player.scale_rating_deviation_to(:v2)
@valid_player_volatility_after_results 0.05999
test "new rating" do
@valid_player_rating_deviation_after_no_results 200.2714 |> Player.scale_rating_deviation_to(:v2)
test "new rating (with results)" do
%Player{rating: new_rating, rating_deviation: new_rating_deviation, volatility: new_volatility} =
Glicko.new_rating(@player, @results, [system_constant: 0.5])
@ -28,4 +30,10 @@ defmodule GlickoTest do
assert_in_delta new_rating_deviation, @valid_player_rating_deviation_after_results, 1.0e-4
assert_in_delta new_volatility, @valid_player_volatility_after_results, 1.0e-5
end
test "new rating (no results)" do
%Player{rating_deviation: new_rating_deviation} = Glicko.new_rating(@player, [])
assert_in_delta new_rating_deviation, @valid_player_rating_deviation_after_no_results, 1.0e-4
end
end