Current section
Files
Jump to
Current section
Files
lib/elo.ex
defmodule Elo do
# TODO: adjustable k-factor
@k_factor 25
@doc """
Calculate new Elo ratings for two given existing ratings (`player_rating`
and `opponent_rating`) and a given `result`.
Result must be 0.0 (first rating loses), 0.5 (draw), or 1.0 (first rating wins).
## Examples
iex(1)> Elo.rate(1000, 500, 1.0)
{1001.3310053800506, 498.66899461994944}
"""
def rate(player, opponent, result) when result in [0.0, 0.5, 1.0] do
{new_rating(player, opponent, result), new_rating(opponent, player, 1.0 - result)}
end
@doc """
Calculate the expected result for the given `player` and `opponent` ratings.
The expected result is expressed as a winning percentage (probability that
`player` will win, plus half the probability of a draw).
"""
def expected_result(player, opponent) do
1.0 / (1.0 + (:math.pow(10.0, ((opponent - player) / 400.0))))
end
defp new_rating(player, opponent, result) do
player
|> expected_result(opponent)
|> elo_change(result)
|> elo_result(player)
end
defp elo_change(expected_result, result) do
@k_factor * (result - expected_result)
end
defp elo_result(change, original) do
change + original
end
end