class Olympic::Rating::Glicko

The Glicko rating system. This is Glicko, not Glicko2.

@see www.glicko.net/glicko/glicko.pdf

Public Class Methods

new(team) click to toggle source
# File lib/olympic/rating/glicko.rb, line 32
def initialize(team)
  @team = team
end
required_fields() click to toggle source

(see Base.required_fields)

# File lib/olympic/rating/glicko.rb, line 23
def self.required_fields
  {
    rating:     [:float, { null: false,
                           default: Formula::DEFAULT_RATING }],
    derivation: [:float, { null: false,
                           default: Formula::DEFAULT_RATING_DERIVATION }]
  }
end

Public Instance Methods

derivation() click to toggle source
# File lib/olympic/rating/glicko.rb, line 51
def derivation
  case
  when unrated?         then 350
  when time_passed == 0 then @team.derivation
  else
    [
      30,
      Math.sqrt(@team.derivation ** 2 +
        CERTAINTY_DECAY * time_passed),
      350
    ].sort[1]
  end
end
rating() click to toggle source
# File lib/olympic/rating/glicko.rb, line 47
def rating
  @team.rating ||= 1500
end
time_passed() click to toggle source
# File lib/olympic/rating/glicko.rb, line 66
def time_passed
  # TODO
  0
end
unrated?() click to toggle source
# File lib/olympic/rating/glicko.rb, line 71
def unrated?
  @team.rating == nil && @team.derivation == nil
end
update(matches) click to toggle source

Updates the rating with the given match information. Matches should be an array of hashes that contain information about those matches.

@param matches [Array<Olympic::Match>] @return [void]

# File lib/olympic/rating/glicko.rb, line 42
def update(matches)
  standardized = standardize_matches(matches)
  Formula.new(self, standardized).call
end

Private Instance Methods

standardize_matches(matches) click to toggle source

@param matches [Array<Olympic::Match>] @return [Array<Hash>]

# File lib/olympic/rating/glicko.rb, line 79
def standardize_matches(matches)
  matches.map do |match|
    raise Rating::Error, "Too many/few incoming sources" unless
      match.incoming.size == 2
    other = match.participants.find { |team| team != @team }
    raise Rating::Error, "Could not find combatant" unless other
    other = Glicko.new(other)
    {
      rating: other.rating,
      derivation: other.derivation,
      outcome: if match.winner == @team then 1 else 0 end
    }
  end
end