Class: ICU::Player
- Inherits:
-
Object
- Object
- ICU::Player
- Extended by:
- Accessor
- Defined in:
- lib/icu_tournament/player.rb,
lib/icu_tournament/tournament_sp.rb,
lib/icu_tournament/tournament_krause.rb
Overview
Player
A player in a tournament must have a first name, a last name and a number which is unique in the tournament but otherwise arbitary.
bobby = ICU::Player.new('robert j', 'fischer', 17)
Names are automatically cannonicalised (tidied up).
bobby.first_name # => 'Robert J.'
bobby.last_name # => 'Fischer'
In addition, players have a number of optional attributes which can be specified via setters or in constructor hash options: id (either FIDE or national), fed (federation), title, rating, rank and dob (date of birth).
peter = ICU::Player.new('Peter', 'Svidler', 21, :fed => 'rus', :title => 'g', :rating = 2700)
peter.dob = '17th June, 1976'
peter.rank = 1
Some of these values will also be canonicalised to some extent. For example, the date of birth conforms to a yyyy-mm-dd format, the chess title will be two to three capital letters always ending in M and the federation, if it’s three letters long, will be upper-cased.
peter.dob # => 1976-07-17
peter.title # => 'GM'
peter.fed # => 'RUS'
It is preferable to add results (ICU::Result) to a player via the tournament (ICU::Tournament) object’s add_result method rather than the method of the same name belonging to player instances. Doing so allows mirrored results to be added to both players with one method call (e.g. one player won, the other lost). A player’s results can later be retieved via the results accessor.
Total scores is available via the points method.
peter.points # => 5.5
A player’s id is their ID number in some external database (typically either ICU or FIDE).
peter.id = 16790 # ICU, or
peter.id = 4102142 # FIDE
Players can be compared to see if they’re roughly or exactly the same, which may be useful in detecting duplicates. If the names match and the federations don’t disagree then two players are equal according to the _==_ operator. The player number is irrelevant.
john1 = ICU::Player.new('John', 'Smith', 12)
john2 = ICU::Player.new('John', 'Smith', 22, :fed = 'IRL')
john2 = ICU::Player.new('John', 'Smith', 32, :fed = 'ENG')
john1 == john2 # => true (federations don't disagree because one is unset)
john2 == john3 # => false (federations disagree)
If, in addition, rating, dob, gender and id do not disagree then two players are equal according to the stricter criteria of eql?.
mark1 = ICU::Player.new('Mark', 'Orr', 31, :fed = 'IRL', :rating => 2100)
mark2 = ICU::Player.new('Mark', 'Orr', 33, :fed = 'IRL', :rating => 2100, :title => 'IM')
mark3 = ICU::Player.new('Mark', 'Orr', 37, :fed = 'IRL', :rating => 2200, :title => 'IM')
mark1.eql?(mark2) # => true (ratings agree and titles don't disagree)
mark2.eql?(mark3) # => false (the ratings are not the same)
The presence of two players in the same tournament that are equal according to _==_ but unequal according to _eql?__ is likely to indicate a data entry error.
If two instances represent the same player and are equal according to _==_ then the id, rating, title and fed attributes of the two can be merged. For example:
fox1 = ICU::Player.new('Tony', 'Fox', 12, :id => 456)
fox2 = ICU::Player.new('Tony', 'Fox', 21, :rating => 2100, :fed => 'IRL', :gender => 'M')
fox1.merge(fox2)
Any attributes present in the second player but not in the first are copied to the first. All other attributes are unaffected.
fox1. # => 2100
fox1.fed # => 'IRL'
fox1.gender # => 'M'
Instance Attribute Summary collapse
-
#fed ⇒ Object
Returns the value of attribute fed.
-
#first_name ⇒ Object
Returns the value of attribute first_name.
-
#gender ⇒ Object
Returns the value of attribute gender.
-
#last_name ⇒ Object
Returns the value of attribute last_name.
-
#results ⇒ Object
readonly
Returns the value of attribute results.
-
#title ⇒ Object
Returns the value of attribute title.
Instance Method Summary collapse
-
#==(other) ⇒ Object
Loose equality test.
-
#add_result(result) ⇒ Object
Add a result.
-
#eql?(other) ⇒ Boolean
Strict equality test.
-
#find_result(round) ⇒ Object
Lookup a result by round number.
-
#initialize(first_name, last_name, num, opt = {}) ⇒ Player
constructor
Constructor.
-
#merge(other) ⇒ Object
Merge in some of the details of another player.
-
#name ⇒ Object
Return the full name, last name first.
-
#points ⇒ Object
Return the player’s total points.
-
#renumber(map) ⇒ Object
Renumber the player according to the supplied hash.
-
#to_krause(rounds) ⇒ Object
Format a player’s 001 record as it would appear in a Krause formatted file (including the final newline).
-
#to_sp_text(rounds, format) ⇒ Object
Format a player’s record as it would appear in an SP text export file.
Methods included from Accessor
attr_accessor, attr_date, attr_date_or_nil, attr_integer, attr_integer_or_nil, attr_positive, attr_positive_or_nil, attr_string, attr_string_or_nil
Constructor Details
#initialize(first_name, last_name, num, opt = {}) ⇒ Player
Constructor. Must supply both names and a unique number for the tournament.
98 99 100 101 102 103 104 105 106 |
# File 'lib/icu_tournament/player.rb', line 98 def initialize(first_name, last_name, num, opt={}) self.first_name = first_name self.last_name = last_name self.num = num [:id, :fed, :title, :rating, :rank, :dob, :gender].each do |atr| self.send("#{atr}=", opt[atr]) unless opt[atr].nil? end @results = [] end |
Instance Attribute Details
#fed ⇒ Object
Returns the value of attribute fed.
95 96 97 |
# File 'lib/icu_tournament/player.rb', line 95 def fed @fed end |
#first_name ⇒ Object
Returns the value of attribute first_name.
95 96 97 |
# File 'lib/icu_tournament/player.rb', line 95 def first_name @first_name end |
#gender ⇒ Object
Returns the value of attribute gender.
95 96 97 |
# File 'lib/icu_tournament/player.rb', line 95 def gender @gender end |
#last_name ⇒ Object
Returns the value of attribute last_name.
95 96 97 |
# File 'lib/icu_tournament/player.rb', line 95 def last_name @last_name end |
#results ⇒ Object (readonly)
Returns the value of attribute results.
95 96 97 |
# File 'lib/icu_tournament/player.rb', line 95 def results @results end |
#title ⇒ Object
Returns the value of attribute title.
95 96 97 |
# File 'lib/icu_tournament/player.rb', line 95 def title @title end |
Instance Method Details
#==(other) ⇒ Object
Loose equality test. Passes if the names match and the federations are not different.
187 188 189 190 191 192 193 194 |
# File 'lib/icu_tournament/player.rb', line 187 def ==(other) return true if equal?(other) return false unless other.is_a? Player return false unless @first_name == other.first_name return false unless @last_name == other.last_name return false if @fed && other.fed && @fed != other.fed true end |
#add_result(result) ⇒ Object
Add a result. Don’t use this method directly - use ICU::Tournament#add_result instead.
154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/icu_tournament/player.rb', line 154 def add_result(result) raise "invalid result" unless result.class == ICU::Result raise "player number (#{@num}) is not matched to result player number (#{result.player})" unless @num == result.player already = @results.find_all { |r| r.round == result.round } return if already.size == 1 && already[0].eql?(result) raise "round number (#{result.round}) of new result is not unique and new result is not the same as existing one" unless already.size == 0 if @results.size == 0 || @results.last.round <= result.round @results << result else i = (0..@results.size-1).find { |n| @results[n].round > result.round } @results.insert(i, result) end end |
#eql?(other) ⇒ Boolean
Strict equality test. Passes if the playes are loosly equal and also if their ID, rating, gender and title are not different.
197 198 199 200 201 202 203 204 |
# File 'lib/icu_tournament/player.rb', line 197 def eql?(other) return true if equal?(other) return false unless self == other [:id, :rating, :title, :gender].each do |m| return false if self.send(m) && other.send(m) && self.send(m) != other.send(m) end true end |
#find_result(round) ⇒ Object
Lookup a result by round number.
169 170 171 |
# File 'lib/icu_tournament/player.rb', line 169 def find_result(round) @results.find { |r| r.round == round } end |
#merge(other) ⇒ Object
Merge in some of the details of another player.
207 208 209 210 211 212 |
# File 'lib/icu_tournament/player.rb', line 207 def merge(other) raise "cannot merge two players that are not equal" unless self == other [:id, :rating, :title, :fed, :gender].each do |m| self.send("#{m}=", other.send(m)) unless self.send(m) end end |
#name ⇒ Object
Return the full name, last name first.
123 124 125 |
# File 'lib/icu_tournament/player.rb', line 123 def name "#{last_name}, #{first_name}" end |
#points ⇒ Object
Return the player’s total points.
174 175 176 |
# File 'lib/icu_tournament/player.rb', line 174 def points @results.inject(0.0) { |t, r| t += r.points } end |
#renumber(map) ⇒ Object
Renumber the player according to the supplied hash. Return self.
179 180 181 182 183 184 |
# File 'lib/icu_tournament/player.rb', line 179 def renumber(map) raise "player number #{@num} not found in renumbering hash" unless map[@num] self.num = map[@num] @results.each{ |r| r.renumber(map) } self end |
#to_krause(rounds) ⇒ Object
Format a player’s 001 record as it would appear in a Krause formatted file (including the final newline).
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 |
# File 'lib/icu_tournament/tournament_krause.rb', line 318 def to_krause(rounds) krause = '001' krause << sprintf(' %4d', @num) krause << sprintf(' %1s', case @gender; when 'M' then 'm'; when 'F' then 'w'; else ''; end) krause << sprintf(' %2s', case @title; when nil then ''; when 'IM' then 'm'; when 'WIM' then 'wm'; else @title[0, @title.length-1].downcase; end) krause << sprintf(' %-33s', "#{@last_name},#{@first_name}") krause << sprintf(' %4s', @rating) krause << sprintf(' %3s', @fed) krause << sprintf(' %11s', @id) krause << sprintf(' %10s', @dob) krause << sprintf(' %4.1f', points) krause << sprintf(' %4s', @rank) (1..rounds).each do |r| result = find_result(r) krause << sprintf(' %8s', result ? result.to_krause : '') end krause << "\n" end |
#to_sp_text(rounds, format) ⇒ Object
Format a player’s record as it would appear in an SP text export file.
362 363 364 365 366 367 368 369 |
# File 'lib/icu_tournament/tournament_sp.rb', line 362 def to_sp_text(rounds, format) attrs = [num.to_s, name, id.to_s, ('%.1f' % points).sub(/\.0/, '')] (1..rounds).each do |r| result = find_result(r) attrs << (result ? result.to_sp_text : " : ") end format % attrs end |