Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ games, and 16 for everybody else.
gem install elo

== Note on Patches/Pull Requests

* Fork the project.
* Make your feature addition or bug fix.
* Add tests for it. This is important so I don't break it in a
Expand Down
2 changes: 0 additions & 2 deletions lib/elo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

# See README.rdoc for general information about Elo.
module Elo

# Accessor to the configuration object, which,
# should be instantiated only once (and automatically).
def self.config
Expand All @@ -22,5 +21,4 @@ def self.config
def self.configure(&block)
yield(config)
end

end
14 changes: 5 additions & 9 deletions lib/elo/configuration.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
module Elo

class Configuration

# This is the lower boundry of the rating you need to be a pro player.
# This setting is used in the FIDE k-factor rules. (default = 2400)
attr_accessor :pro_rating_boundry
Expand All @@ -19,9 +17,9 @@ class Configuration

# Use the settings that FIDE use for determening the K-factor.
# This is the case when all settings are unaltered. (default = true)
#
#
# In short:
#
#
# * K-factor is 25 when a player is a starter (less than 30 games played)
# * K-factor is 10 when a player is a pro (rating above 2400, now or in the past)
# * K-factor is 15 when a player in other cases
Expand Down Expand Up @@ -72,12 +70,10 @@ def k_factors

def apply_fide_k_factors
unless @applied_fide_k_factors
k_factor(10) { pro? or pro_rating? }
k_factor(25) { starter? }
@applied_fide_k_factors = true
k_factor(10) { pro? or pro_rating? }
k_factor(25) { starter? }
@applied_fide_k_factors = true
end
end

end

end
70 changes: 35 additions & 35 deletions lib/elo/game.rb
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
module Elo

# A Game is a collection of two Elo::Player objects
# and a result.
# Once the result is known, it propagates the new
# ratings to the players.
# A Game is a collection of two Elo::Player objects
# and a result.
# Once the result is known, it propagates the new
# ratings to the players.
class Game

include Helper

# The result is the result of the match. It's a nubmer
# from 0 to 1 from the perspective of player +:one+.
# The result is the result of the match. It's a nubmer
# from 0 to 1 from the perspective of player +:one+.
attr_reader :result

# The first Elo::Player. The result is in perspecive of
# this player.
# The first Elo::Player. The result is in perspecive of
# this player.
attr_reader :one

# The second Elo::Player.
# The second Elo::Player.
attr_reader :two

# Every time a result is set, it tells the Elo::Player
# objects to update their scores.
# objects to update their scores.
def process_result(result)
@result = result
calculate
Expand All @@ -36,41 +34,41 @@ def calculate
self
end

# Player +:one+ has won!
# This is a shortcut method for setting the score to 1
# Player +:one+ has won!
# This is a shortcut method for setting the score to 1
def win
process_result 1.0
end

# Player +:one+ has lost!
# This is a shortcut method for setting the score to 0
# Player +:one+ has lost!
# This is a shortcut method for setting the score to 0
def lose
process_result 0.0
end

# It was a draw.
# This is a shortcut method for setting the score to 0.5
# It was a draw.
# This is a shortcut method for setting the score to 0.5
def draw
process_result 0.5
end

# You can override this method if you store each game
# in a database or something like that.
# This method will be called when a result is known.
# in a database or something like that.
# This method will be called when a result is known.
def save
end

# Set the winner. Provide it with a Elo::Player.
# Set the winner. Provide it with a Elo::Player.
def winner=(player)
process_result(player == one ? 1.0 : 0.0)
end

# Set the loser. Provide it with a Elo::Player.
# Set the loser. Provide it with a Elo::Player.
def loser=(player)
process_result(player == one ? 0.0 : 1.0)
end

# Access the Elo::Rating objects for both players.
# Access the Elo::Rating objects for both players.
def ratings
@ratings ||= { one => rating_one, two => rating_two }
end
Expand All @@ -81,22 +79,24 @@ def inspect

private

# Create an Elo::Rating object for player one
# Create an Elo::Rating object for player one
def rating_one
Rating.new(:result => result,
:old_rating => one.rating,
:other_rating => two.rating,
:k_factor => one.k_factor)
Rating.new(
result: result,
old_rating: one.rating,
other_rating: two.rating,
k_factor: one.k_factor
)
end

# Create an Elo::Rating object for player two
# Create an Elo::Rating object for player two
def rating_two
Rating.new(:result => (1.0 - result),
:old_rating => two.rating,
:other_rating => one.rating,
:k_factor => two.k_factor)
Rating.new(
result: 1.0 - result,
old_rating: two.rating,
other_rating: one.rating,
k_factor: two.k_factor
)
end

end

end
10 changes: 3 additions & 7 deletions lib/elo/helper.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
module Elo

module Helper

module Helper
# Every object can be initialized with a hash,
# almost, but not quite, entirely unlike ActiveRecord.
# almost, but not quite, entirely unlike ActiveRecord.
def initialize(attributes = {})
attributes.each do |key, value|
instance_variable_set("@#{key}", value)
end
end

end

end
end
68 changes: 32 additions & 36 deletions lib/elo/player.rb
Original file line number Diff line number Diff line change
@@ -1,63 +1,61 @@
module Elo

# A player. You need at least two play a Game.
class Player

include Helper

# The rating you provided, or the default rating from configuration
def rating
@rating ||= Elo.config.default_rating
end

# The number of games played is needed for calculating the K-factor.
# The number of games played is needed for calculating the K-factor.
def games_played
@games_played ||= games.size
end

# A list of games played by the player.
# A list of games played by the player.
def games
@games ||= []
end

# Is the player considered a pro, because his/her rating crossed
# the threshold configured? This is needed for calculating the K-factor.
# Is the player considered a pro, because his/her rating crossed
# the threshold configured? This is needed for calculating the K-factor.
def pro_rating?
rating >= Elo.config.pro_rating_boundry
end

# Is the player just starting? Provide the boundry for
# the amount of games played in the configuration.
# This is needed for calculating the K-factor.
# Is the player just starting? Provide the boundry for
# the amount of games played in the configuration.
# This is needed for calculating the K-factor.
def starter?
games_played < Elo.config.starter_boundry
end

# FIDE regulations specify that once you reach a pro status
# (see +pro_rating?+), you are considered a pro for life.
#
# You might need to specify it manually, when depending on
# external persistence of players.
#
# Elo::Player.new(:pro => true)
# FIDE regulations specify that once you reach a pro status
# (see +pro_rating?+), you are considered a pro for life.
#
# You might need to specify it manually, when depending on
# external persistence of players.
#
# Elo::Player.new(:pro => true)
def pro?
!!@pro
end

# You can override this method if you store each game
# in a database or something like that.
# This method will be called when a result is known.
# in a database or something like that.
# This method will be called when a result is known.
def save
end

# Calculates the K-factor for the player.
# Elo allows you specify custom Rules (see Elo::Configuration).
#
# You can set it manually, if you wish:
#
# Elo::Player.new(:k_factor => 10)
#
# This stops this player from using the K-factor rules.
# Calculates the K-factor for the player.
# Elo allows you specify custom Rules (see Elo::Configuration).
#
# You can set it manually, if you wish:
#
# Elo::Player.new(:k_factor => 10)
#
# This stops this player from using the K-factor rules.
def k_factor
return @k_factor if @k_factor
Elo.config.applied_k_factors.each do |rule|
Expand All @@ -66,26 +64,26 @@ def k_factor
Elo.config.default_k_factor
end

# Start a game with another player. At this point, no
# result is known and nothing really happens.
# Start a game with another player. At this point, no
# result is known and nothing really happens.
def versus(other_player, options = {})
Game.new(options.merge(:one => self, :two => other_player)).calculate
end

# Start a game with another player and set the score
# immediately.
# Start a game with another player and set the score
# immediately.
def wins_from(other_player, options = {})
versus(other_player, options).win
end

# Start a game with another player and set the score
# immediately.
# Start a game with another player and set the score
# immediately.
def plays_draw(other_player, options = {})
versus(other_player, options).draw
end

# Start a game with another player and set the score
# immediately.
# Start a game with another player and set the score
# immediately.
def loses_from(other_player, options = {})
versus(other_player, options).lose
end
Expand All @@ -108,7 +106,5 @@ def played(game)
@pro = true if pro_rating?
save
end

end

end
Loading