Class: EloRating::Match::Player

Inherits:
Object
  • Object
show all
Defined in:
lib/elo_rating/match.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(match:, rating:, place: nil, winner: nil) ⇒ Player



55
56
57
58
59
60
61
# File 'lib/elo_rating/match.rb', line 55

def initialize(match:, rating:, place: nil, winner: nil)
  validate_attributes!(rating: rating, place: place, winner: winner)
  @match = match
  @rating = rating
  @place = place
  @winner = winner
end

Instance Attribute Details

#matchObject (readonly)

:nodoc:



54
55
56
# File 'lib/elo_rating/match.rb', line 54

def match
  @match
end

#placeObject (readonly)

:nodoc:



54
55
56
# File 'lib/elo_rating/match.rb', line 54

def place
  @place
end

#ratingObject (readonly)

:nodoc:



54
55
56
# File 'lib/elo_rating/match.rb', line 54

def rating
  @rating
end

Instance Method Details

#actual_score_against(opponent) ⇒ Object



99
100
101
102
103
104
105
106
107
# File 'lib/elo_rating/match.rb', line 99

def actual_score_against(opponent)
  if won_against?(opponent)
    1
  elsif opponent.won_against?(self)
    0
  else # draw
    0.5
  end
end

#expected_score_against(opponent) ⇒ Object



95
96
97
# File 'lib/elo_rating/match.rb', line 95

def expected_score_against(opponent)
  EloRating.expected_score(rating, opponent.rating)
end

#opponentsObject



73
74
75
# File 'lib/elo_rating/match.rb', line 73

def opponents
  match.players - [self]
end

#placed_ahead_of?(opponent) ⇒ Boolean



113
114
115
116
117
# File 'lib/elo_rating/match.rb', line 113

def placed_ahead_of?(opponent)
  if place && opponent.place
    place < opponent.place
  end
end

#rating_adjustment_against(opponent) ⇒ Object



87
88
89
90
91
92
93
# File 'lib/elo_rating/match.rb', line 87

def rating_adjustment_against(opponent)
  EloRating.rating_adjustment(
    expected_score_against(opponent),
    actual_score_against(opponent),
    rating: rating
  )
end

#total_rating_adjustmentsObject



81
82
83
84
85
# File 'lib/elo_rating/match.rb', line 81

def total_rating_adjustments
  opponents.map do |opponent|
    rating_adjustment_against(opponent)
  end.reduce(0, :+)
end

#updated_ratingObject



77
78
79
# File 'lib/elo_rating/match.rb', line 77

def updated_rating
  (rating + total_rating_adjustments).round
end

#validate_attributes!(rating:, place:, winner:) ⇒ Object

Raises:

  • (ArgumentError)


67
68
69
70
71
# File 'lib/elo_rating/match.rb', line 67

def validate_attributes!(rating:, place:, winner:)
  raise ArgumentError, 'Rating must be numeric' unless rating.is_a? Numeric
  raise ArgumentError, 'Winner and place cannot both be specified' if place && winner
  raise ArgumentError, 'Place must be numeric' unless place.nil? || place.is_a?(Numeric)
end

#winner?Boolean



63
64
65
# File 'lib/elo_rating/match.rb', line 63

def winner?
  @winner
end

#won_against?(opponent) ⇒ Boolean



109
110
111
# File 'lib/elo_rating/match.rb', line 109

def won_against?(opponent)
  winner? || placed_ahead_of?(opponent)
end