Class: EloRankable::Calculator

Inherits:
Object
  • Object
show all
Defined in:
lib/elo_rankable/calculator.rb

Class Method Summary collapse

Class Method Details

.expected_score(rating_a, rating_b) ⇒ Object

Calculate expected score for player A against player B



7
8
9
# File 'lib/elo_rankable/calculator.rb', line 7

def expected_score(rating_a, rating_b)
  1.0 / (1.0 + (10.0**((rating_b - rating_a) / 400.0)))
end

.update_ratings_for_draw(player1, player2) ⇒ Object

Update ratings after a draw

Raises:

  • (ArgumentError)


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/elo_rankable/calculator.rb', line 35

def update_ratings_for_draw(player1, player2)
  player1_rating = player1.elo_ranking
  player2_rating = player2.elo_ranking

  # Defensive validation - these should be caught earlier but just in case
  raise ArgumentError, "Player1's elo_ranking is nil" if player1_rating.nil?
  raise ArgumentError, "Player2's elo_ranking is nil" if player2_rating.nil?

  player1_expected = expected_score(player1_rating.rating, player2_rating.rating)
  player2_expected = expected_score(player2_rating.rating, player1_rating.rating)

  player1_k = player1_rating.k_factor
  player2_k = player2_rating.k_factor

  # Both players get 0.5 points in a draw
  player1_new_rating = player1_rating.rating + (player1_k * (0.5 - player1_expected))
  player2_new_rating = player2_rating.rating + (player2_k * (0.5 - player2_expected))

  update_ranking(player1_rating, player1_new_rating)
  update_ranking(player2_rating, player2_new_rating)
end

.update_ratings_for_win(winner, loser) ⇒ Object

Update ratings after a match where player1 beats player2

Raises:

  • (ArgumentError)


12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/elo_rankable/calculator.rb', line 12

def update_ratings_for_win(winner, loser)
  winner_rating = winner.elo_ranking
  loser_rating = loser.elo_ranking

  # Defensive validation - these should be caught earlier but just in case
  raise ArgumentError, "Winner's elo_ranking is nil" if winner_rating.nil?
  raise ArgumentError, "Loser's elo_ranking is nil" if loser_rating.nil?

  winner_expected = expected_score(winner_rating.rating, loser_rating.rating)
  loser_expected = expected_score(loser_rating.rating, winner_rating.rating)

  winner_k = winner_rating.k_factor
  loser_k = loser_rating.k_factor

  # Winner gets 1 point, loser gets 0 points
  winner_new_rating = winner_rating.rating + (winner_k * (1 - winner_expected))
  loser_new_rating = loser_rating.rating + (loser_k * (0 - loser_expected))

  update_ranking(winner_rating, winner_new_rating)
  update_ranking(loser_rating, loser_new_rating)
end