icu_tournament 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/icu_tournament/tournament.rb +16 -13
- data/lib/icu_tournament/tournament_sp.rb +15 -18
- data/lib/icu_tournament/version.rb +1 -1
- data/spec/tournament_sp_spec.rb +2 -10
- data/spec/tournament_spec.rb +67 -45
- metadata +1 -1
@@ -101,6 +101,8 @@ The full list of supported methods is:
|
|
101
101
|
* _Harkness_ (or _median_): like Buchholz except the highest and lowest opponents' scores are discarded (or two highest and lowest if 9 rounds or more)
|
102
102
|
* _modified_median_: same as Harkness except only lowest (or highest) score(s) are discarded for players with more (or less) than 50%
|
103
103
|
* _Neustadtl_ (or _Sonneborn-Berger_): sum of scores of players defeated plus half sum of scores of players drawn against
|
104
|
+
* _progressive_ (or _cumulative_): sum of running score for each round
|
105
|
+
* _ratings_: sum of opponents ratings
|
104
106
|
* _blacks_: number of blacks
|
105
107
|
* _wins_: number of wins
|
106
108
|
* _name_: alphabetical by name (if _tie_breaks_ is set to an empty array, as it is initially, then this will be used as the back-up tie breaker)
|
@@ -215,12 +217,13 @@ The return value from _renumber_ is the tournament object itself.
|
|
215
217
|
when 'sonneborn_berger' then 'neustadtl'
|
216
218
|
when 'modified_median' then 'modified'
|
217
219
|
when 'median' then 'harkness'
|
220
|
+
when 'cumulative' then 'progressive'
|
218
221
|
else m
|
219
222
|
end
|
220
223
|
end
|
221
224
|
|
222
225
|
# Check they're all valid.
|
223
|
-
tie_breaks.each { |m| raise "invalid tie break method '#{m}'" unless m.to_s.match(/^(blacks|buchholz|harkness|modified|name|neustadtl|wins)$/) }
|
226
|
+
tie_breaks.each { |m| raise "invalid tie break method '#{m}'" unless m.to_s.match(/^(blacks|buchholz|harkness|modified|name|neustadtl|progressive|ratings|wins)$/) }
|
224
227
|
|
225
228
|
# Finally set them.
|
226
229
|
@tie_breaks = tie_breaks;
|
@@ -469,27 +472,25 @@ The return value from _renumber_ is the tournament object itself.
|
|
469
472
|
# Add the configured methods.
|
470
473
|
tie_breaks.each do |m|
|
471
474
|
methods << m
|
472
|
-
order[m] = -1
|
475
|
+
order[m] = m == 'name' ? 1 : -1
|
473
476
|
end
|
474
477
|
|
475
478
|
# Name is included as the last and least important tie breaker unless it's already been added.
|
476
479
|
unless methods.include?('name')
|
477
480
|
methods << 'name'
|
478
|
-
order['name'] =
|
481
|
+
order['name'] = 1
|
479
482
|
end
|
480
483
|
|
481
484
|
# We'll need the number of rounds.
|
482
485
|
rounds = last_round
|
483
486
|
|
484
|
-
# Pre-calculate some scores that are not in themselves tie break
|
487
|
+
# Pre-calculate some scores that are not in themselves tie break scores
|
485
488
|
# but are needed in the calculation of some of the actual tie-break scores.
|
486
489
|
pre_calculated = Array.new
|
487
490
|
pre_calculated << 'opp-score' # sum scores where a non-played games counts 0.5
|
488
491
|
pre_calculated.each do |m|
|
489
492
|
data[m] = Hash.new
|
490
|
-
@player.values.each
|
491
|
-
data[m][p.num] = tie_break_score(data, m, p, rounds)
|
492
|
-
end
|
493
|
+
@player.values.each { |p| data[m][p.num] = tie_break_score(data, m, p, rounds) }
|
493
494
|
end
|
494
495
|
|
495
496
|
# Now calculate all the other scores.
|
@@ -506,12 +507,14 @@ The return value from _renumber_ is the tournament object itself.
|
|
506
507
|
# Return a tie break score for a given player and a given tie break method.
|
507
508
|
def tie_break_score(hash, method, player, rounds)
|
508
509
|
case method
|
509
|
-
when 'score'
|
510
|
-
when 'wins'
|
511
|
-
when 'blacks'
|
512
|
-
when 'buchholz'
|
513
|
-
when 'neustadtl'
|
514
|
-
when 'opp-score'
|
510
|
+
when 'score' then player.points
|
511
|
+
when 'wins' then player.results.inject(0) { |t,r| t + (r.opponent && r.score == 'W' ? 1 : 0) }
|
512
|
+
when 'blacks' then player.results.inject(0) { |t,r| t + (r.opponent && r.colour == 'B' ? 1 : 0) }
|
513
|
+
when 'buchholz' then player.results.inject(0.0) { |t,r| t + (r.opponent ? hash['opp-score'][r.opponent] : 0.0) }
|
514
|
+
when 'neustadtl' then player.results.inject(0.0) { |t,r| t + (r.opponent ? hash['opp-score'][r.opponent] * r.points : 0.0) }
|
515
|
+
when 'opp-score' then player.results.inject(0.0) { |t,r| t + (r.opponent ? r.points : 0.5) } + (rounds - player.results.size) * 0.5
|
516
|
+
when 'progressive' then (1..rounds).inject(0.0) { |t,n| r = player.find_result(n); s = r ? r.points : 0.0; t + s * (rounds + 1 - n) }
|
517
|
+
when 'ratings' then player.results.inject(0) { |t,r| t + (r.opponent && @player[r.opponent].rating ? @player[r.opponent].rating : 0) }
|
515
518
|
when 'harkness', 'modified'
|
516
519
|
scores = player.results.map{ |r| r.opponent ? hash['opp-score'][r.opponent] : 0.0 }.sort
|
517
520
|
1.upto(rounds - player.results.size) { scores << 0.0 }
|
@@ -39,7 +39,7 @@ ratings or IDs are required instead, use the options _id_ and _rating_. For exam
|
|
39
39
|
tournament = parser.parse_file('ncc', "2010-05-08")
|
40
40
|
tournament.player(2).id # => 12379 (ICU ID)
|
41
41
|
tournament.player(2).rating # => 2556 (ICU rating)
|
42
|
-
|
42
|
+
|
43
43
|
tournament = parser.parse_file('ncc', "2010-05-08", :id => :intl, :rating => :intl)
|
44
44
|
tournament.player(2).id # => 1205064 (FIDE ID)
|
45
45
|
tournament.player(2).rating # => 2530 (FIDE rating)
|
@@ -78,10 +78,6 @@ Should you wish to rank the tournament using a different set of tie-break rules,
|
|
78
78
|
tournament.tie_breaks = [:wins, :blacks]
|
79
79
|
swiss_perfect = tournament.rerank.renumber.serialize('SwissPerfect')
|
80
80
|
|
81
|
-
== Todo
|
82
|
-
|
83
|
-
* Implement the extra tie-break rules that SP has
|
84
|
-
|
85
81
|
=end
|
86
82
|
|
87
83
|
class SwissPerfect
|
@@ -182,9 +178,10 @@ Should you wish to rank the tournament using a different set of tie-break rules,
|
|
182
178
|
ext = $2.downcase
|
183
179
|
stem[ext] = stm
|
184
180
|
tmp = Tempfile.new(e.name)
|
185
|
-
tmp.
|
186
|
-
|
187
|
-
|
181
|
+
pth = tmp.path
|
182
|
+
tmp.close!
|
183
|
+
e.extract(pth) { true }
|
184
|
+
temp[ext] = pth
|
188
185
|
end
|
189
186
|
end
|
190
187
|
%w(ini trn sco).each { |ext| raise "no #{ext.upcase} file found" unless stem[ext] }
|
@@ -210,17 +207,17 @@ Should you wish to rank the tournament using a different set of tie-break rules,
|
|
210
207
|
@t.send("#{key}=", val) if val.size > 0
|
211
208
|
end
|
212
209
|
@t.tie_breaks = ini['Standings']['Tie Breaks'].to_s.split(/,/).map do |tbid|
|
213
|
-
case tbid.to_i
|
214
|
-
when 1217 then :buchholz
|
215
|
-
when 1218 then :harkness
|
216
|
-
when 1219 then
|
217
|
-
when 1220 then :neustadtl
|
218
|
-
when 1221 then
|
219
|
-
when 1222 then :wins
|
220
|
-
when 1223 then nil
|
221
|
-
when 1226 then nil
|
210
|
+
case tbid.to_i # tie break name in SwissPerfect
|
211
|
+
when 1217 then :buchholz # Buchholz
|
212
|
+
when 1218 then :harkness # Median Buchholz
|
213
|
+
when 1219 then :progressive # cumulative
|
214
|
+
when 1220 then :neustadtl # Berger
|
215
|
+
when 1221 then :ratings # rating sum
|
216
|
+
when 1222 then :wins # number of wins
|
217
|
+
when 1223 then nil # minor scores - not applicable
|
218
|
+
when 1226 then nil # Brightwell - not applicable
|
222
219
|
else nil
|
223
|
-
end
|
220
|
+
end
|
224
221
|
end.find_all { |tb| tb }
|
225
222
|
end
|
226
223
|
|
data/spec/tournament_sp_spec.rb
CHANGED
@@ -49,7 +49,7 @@ module ICU
|
|
49
49
|
end
|
50
50
|
|
51
51
|
it "should have the correct tie breaks" do
|
52
|
-
@t.tie_breaks.join('|').should == "buchholz|harkness"
|
52
|
+
@t.tie_breaks.join('|').should == "buchholz|harkness|progressive"
|
53
53
|
end
|
54
54
|
|
55
55
|
it "should serialize to the text export format" do
|
@@ -116,7 +116,7 @@ module ICU
|
|
116
116
|
end
|
117
117
|
|
118
118
|
it "should have the correct tie breaks" do
|
119
|
-
@t.tie_breaks.join('|').should == "harkness|buchholz"
|
119
|
+
@t.tie_breaks.join('|').should == "harkness|buchholz|progressive"
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
@@ -271,14 +271,6 @@ module ICU
|
|
271
271
|
@t.player(8).signature.should == "Vega, Marcos Llaneza||2475|3.0|16|1234|DDWW|BWBW|TTTT"
|
272
272
|
@t.player(67).signature.should == "Lee, Shane|780|1633|1.0|52|134|DLD|WWW|TTT"
|
273
273
|
end
|
274
|
-
|
275
|
-
it "should have correct details for selection of players, including international IDs and ratings when so configured" do
|
276
|
-
@t = @p.parse_file(SAMPLES + 'ncc', "2010-05-08", :id => :intl, :rating => :intl)
|
277
|
-
@t.player(2).signature.should == "Szabo, Gergely|1205064||4.0|4|1234|WWWW|WBWB|TTTT"
|
278
|
-
@t.player(5).signature.should == "Daly, Colm|2500434||3.5|7|1234|WWWD|WBWB|TTTT"
|
279
|
-
@t.player(8).signature.should == "Vega, Marcos Llaneza|2253585||3.0|16|1234|DDWW|BWBW|TTTT"
|
280
|
-
@t.player(67).signature.should == "Lee, Shane|||1.0|52|134|DLD|WWW|TTT"
|
281
|
-
end
|
282
274
|
end
|
283
275
|
end
|
284
276
|
end
|
data/spec/tournament_spec.rb
CHANGED
@@ -16,7 +16,7 @@ module ICU
|
|
16
16
|
end.should_not raise_error
|
17
17
|
end
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
context "documentation example" do
|
21
21
|
before(:each) do
|
22
22
|
@t = t = ICU::Tournament.new('Bangor Masters', '2009-11-09')
|
@@ -35,12 +35,12 @@ module ICU
|
|
35
35
|
001 30 Orr,Mark 0.5 3 10 b = 20 w 0
|
36
36
|
EOS
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
it "should serialize to Krause" do
|
40
40
|
parser = ICU::Tournament::Krause.new
|
41
41
|
parser.serialize(@t).should == @s
|
42
42
|
end
|
43
|
-
end
|
43
|
+
end
|
44
44
|
|
45
45
|
context "name" do
|
46
46
|
before(:each) do
|
@@ -57,8 +57,8 @@ EOS
|
|
57
57
|
end
|
58
58
|
|
59
59
|
it "should not be blank or without letters" do
|
60
|
-
lambda { Tournament.new(' ', '2009-11-09') }.should raise_error(/invalid.*name/)
|
61
|
-
lambda { @t.name = '333' }.should raise_error(/invalid.*name/)
|
60
|
+
lambda { Tournament.new(' ', '2009-11-09') }.should raise_error(/invalid.*name/)
|
61
|
+
lambda { @t.name = '333' }.should raise_error(/invalid.*name/)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
@@ -262,17 +262,17 @@ EOS
|
|
262
262
|
lambda { @t.time_control = 'abc' }.should raise_error(/invalid.*time.*control/)
|
263
263
|
end
|
264
264
|
end
|
265
|
-
|
265
|
+
|
266
266
|
context "tie breaks" do
|
267
267
|
before(:each) do
|
268
268
|
@t = Tournament.new('Edinburgh Masters', '2009-11-09')
|
269
269
|
end
|
270
|
-
|
270
|
+
|
271
271
|
it "should an empty tie breaks list by default" do
|
272
272
|
@t.tie_breaks.should be_an_instance_of(Array)
|
273
273
|
@t.tie_breaks.should be_empty
|
274
274
|
end
|
275
|
-
|
275
|
+
|
276
276
|
it "should be settable to one or more valid tie break methods" do
|
277
277
|
@t.tie_breaks = [:neustadtl]
|
278
278
|
@t.tie_breaks.join('|').should == "neustadtl"
|
@@ -283,11 +283,11 @@ EOS
|
|
283
283
|
@t.tie_breaks = []
|
284
284
|
@t.tie_breaks.join('|').should == ""
|
285
285
|
end
|
286
|
-
|
286
|
+
|
287
287
|
it "should rasie an error is not given an array" do
|
288
288
|
lambda { @t.tie_breaks = :neustadtl }.should raise_error(/array/i)
|
289
289
|
end
|
290
|
-
|
290
|
+
|
291
291
|
it "should rasie an error is given any invalid tie-break methods" do
|
292
292
|
lambda { @t.tie_breaks = ["My Bum"] }.should raise_error(/invalid/i)
|
293
293
|
lambda { @t.tie_breaks = [:neustadtl, "Your arse"] }.should raise_error(/invalid/i)
|
@@ -370,7 +370,7 @@ EOS
|
|
370
370
|
@t.find_player(Player.new('John', 'Orr', 4, :fed => 'IRL')).should be_nil
|
371
371
|
end
|
372
372
|
end
|
373
|
-
|
373
|
+
|
374
374
|
context "teams" do
|
375
375
|
before(:each) do
|
376
376
|
@t = Tournament.new('Bangor Bash', '2009-11-09')
|
@@ -382,20 +382,20 @@ EOS
|
|
382
382
|
@t.get_team(' wandering dragons ').should be_an_instance_of Team
|
383
383
|
@t.get_team('Blundering Bishops').should be_nil
|
384
384
|
end
|
385
|
-
|
385
|
+
|
386
386
|
it "should be able to create and add a new team and retrieve it" do
|
387
387
|
@t.add_team('Blundering Bishops').should be_an_instance_of Team
|
388
388
|
@t.get_team(' blundering bishops ').should be_an_instance_of Team
|
389
389
|
@t.get_team('Wandering Dragons').should be_nil
|
390
390
|
end
|
391
|
-
|
391
|
+
|
392
392
|
it "should throw and exception if there is an attempt to add a team with a name that matches an existing team" do
|
393
393
|
lambda { @t.add_team('Blundering Bishops') }.should_not raise_error
|
394
394
|
lambda { @t.add_team('Wandering Dragons') }.should_not raise_error
|
395
395
|
lambda { @t.add_team(' wandering dragons ') }.should raise_error(/similar.*exists/)
|
396
396
|
end
|
397
397
|
end
|
398
|
-
|
398
|
+
|
399
399
|
context "validation" do
|
400
400
|
before(:each) do
|
401
401
|
@t = Tournament.new('Edinburgh Masters', '2009-11-09')
|
@@ -465,7 +465,7 @@ EOS
|
|
465
465
|
@t.player(3).rank = 3
|
466
466
|
lambda { @t.validate! }.should raise_error(/player 2.*above.*player 1/)
|
467
467
|
end
|
468
|
-
|
468
|
+
|
469
469
|
it "should be valid if there are teams, every player is in one of them, and no team has an invalid member" do
|
470
470
|
team1 = Team.new('International Masters')
|
471
471
|
team2 = Team.new('World Champions')
|
@@ -479,7 +479,7 @@ EOS
|
|
479
479
|
team1.add_member(4)
|
480
480
|
@t.invalid.should match(/not.*valid/)
|
481
481
|
end
|
482
|
-
|
482
|
+
|
483
483
|
it "should not be valid if one player is in more than one team" do
|
484
484
|
team1 = Team.new('XInternational Masters')
|
485
485
|
team1.add_member(1)
|
@@ -493,7 +493,7 @@ EOS
|
|
493
493
|
@t.invalid.should match(/already.*member/)
|
494
494
|
end
|
495
495
|
end
|
496
|
-
|
496
|
+
|
497
497
|
context "renumbering" do
|
498
498
|
before(:each) do
|
499
499
|
@t = Tournament.new('Edinburgh Masters', '2009-11-09')
|
@@ -504,7 +504,7 @@ EOS
|
|
504
504
|
@t.add_result(Result.new(2, 30, 'W', :opponent => 10))
|
505
505
|
@t.add_result(Result.new(3, 20, 'W', :opponent => 30))
|
506
506
|
end
|
507
|
-
|
507
|
+
|
508
508
|
it "sample tournament is valid but unranked" do
|
509
509
|
@t.invalid.should be_false
|
510
510
|
@t.player(10).rank.should be_nil
|
@@ -518,7 +518,7 @@ EOS
|
|
518
518
|
@t.players.map{ |p| p.num }.join('|').should == '1|2|3'
|
519
519
|
@t.players.map{ |p| p.last_name }.join('|').should == 'Fischer|Kasparov|Orr'
|
520
520
|
end
|
521
|
-
|
521
|
+
|
522
522
|
it "should be renumberable by rank if the tournament is ranked" do
|
523
523
|
@t.rerank.renumber
|
524
524
|
@t.invalid.should be_false
|
@@ -526,7 +526,7 @@ EOS
|
|
526
526
|
@t.players.map{ |p| p.rank }.join('|').should == '1|2|3'
|
527
527
|
@t.players.map{ |p| p.last_name }.join('|').should == 'Orr|Kasparov|Fischer'
|
528
528
|
end
|
529
|
-
|
529
|
+
|
530
530
|
it "should be renumberable by name even if the tourament is ranked" do
|
531
531
|
@t.rerank.renumber(:name)
|
532
532
|
@t.invalid.should be_false
|
@@ -545,12 +545,12 @@ EOS
|
|
545
545
|
context "reranking" do
|
546
546
|
before(:each) do
|
547
547
|
@t = Tournament.new('Edinburgh Masters', '2009-11-09')
|
548
|
-
@t.add_player(@boby = Player.new('Bobby', 'Fischer', 1))
|
549
|
-
@t.add_player(@gary = Player.new('Gary', 'Kasparov', 2))
|
548
|
+
@t.add_player(@boby = Player.new('Bobby', 'Fischer', 1, :rating => 2600))
|
549
|
+
@t.add_player(@gary = Player.new('Gary', 'Kasparov', 2, :rating => 2700))
|
550
550
|
@t.add_player(@boby = Player.new('Micky', 'Mouse', 3))
|
551
|
-
@t.add_player(@boby = Player.new('Minnie', 'Mouse', 4))
|
552
|
-
@t.add_player(@boby = Player.new('Gearoidin', 'Ui Laighleis', 5))
|
553
|
-
@t.add_player(@mark = Player.new('Mark', 'Orr', 6))
|
551
|
+
@t.add_player(@boby = Player.new('Minnie', 'Mouse', 4, :rating => 1500))
|
552
|
+
@t.add_player(@boby = Player.new('Gearoidin', 'Ui Laighleis', 5, :rating => 1700))
|
553
|
+
@t.add_player(@mark = Player.new('Mark', 'Orr', 6, :rating => 2300))
|
554
554
|
@t.add_result(Result.new(1, 1, 'W', :opponent => 6, :colour => 'W'))
|
555
555
|
@t.add_result(Result.new(2, 1, 'W', :opponent => 3, :colour => 'B'))
|
556
556
|
@t.add_result(Result.new(3, 1, 'W', :opponent => 5, :colour => 'W'))
|
@@ -566,13 +566,13 @@ EOS
|
|
566
566
|
@t.invalid.should be_false
|
567
567
|
@t.player(1).rank.should be_nil
|
568
568
|
end
|
569
|
-
|
569
|
+
|
570
570
|
it "should have correct default tie break scores" do
|
571
571
|
scores = @t.tie_break_scores
|
572
572
|
scores[1].should == 'Fischer, Bobby'
|
573
573
|
scores[5].should == 'Ui Laighleis, Gearoidin'
|
574
574
|
end
|
575
|
-
|
575
|
+
|
576
576
|
it "should have correct actual scores" do
|
577
577
|
@t.player(1).points.should == 3.0
|
578
578
|
@t.player(2).points.should == 3.0
|
@@ -581,7 +581,7 @@ EOS
|
|
581
581
|
@t.player(5).points.should == 0.5
|
582
582
|
@t.player(6).points.should == 0.5
|
583
583
|
end
|
584
|
-
|
584
|
+
|
585
585
|
it "should have correct Buchholz tie break scores" do
|
586
586
|
@t.tie_breaks = ["Buchholz"]
|
587
587
|
scores = @t.tie_break_scores
|
@@ -592,7 +592,7 @@ EOS
|
|
592
592
|
scores[5].should == 6.5
|
593
593
|
scores[6].should == 4.5
|
594
594
|
end
|
595
|
-
|
595
|
+
|
596
596
|
it "Buchholz should be sensitive to unplayed games" do
|
597
597
|
@t.player(1).find_result(1).opponent = nil
|
598
598
|
@t.player(6).find_result(1).opponent = nil
|
@@ -605,7 +605,29 @@ EOS
|
|
605
605
|
scores[5].should == 6.5 # 3 from Fischer changed to 2.5, 0.5 from Orr changed to 1 (cancels out)
|
606
606
|
scores[6].should == 1.5 # 3 from Fischer changed to 0
|
607
607
|
end
|
608
|
-
|
608
|
+
|
609
|
+
it "should have correct progressive tie break scores" do
|
610
|
+
@t.tie_breaks = [:progressive]
|
611
|
+
scores = @t.tie_break_scores
|
612
|
+
scores[1].should == 6.0
|
613
|
+
scores[2].should == 6.0
|
614
|
+
scores[3].should == 3.0
|
615
|
+
scores[4].should == 1.0
|
616
|
+
scores[5].should == 1.0
|
617
|
+
scores[6].should == 1.0
|
618
|
+
end
|
619
|
+
|
620
|
+
it "should have correct ratings tie break scores" do
|
621
|
+
@t.tie_breaks = ['ratings']
|
622
|
+
scores = @t.tie_break_scores
|
623
|
+
scores[1].should == 4000
|
624
|
+
scores[2].should == 3200
|
625
|
+
scores[3].should == 6800
|
626
|
+
scores[4].should == 5000
|
627
|
+
scores[5].should == 7600
|
628
|
+
scores[6].should == 5800
|
629
|
+
end
|
630
|
+
|
609
631
|
it "should have correct Neustadtl tie break scores" do
|
610
632
|
@t.tie_breaks = [:neustadtl]
|
611
633
|
scores = @t.tie_break_scores
|
@@ -616,7 +638,7 @@ EOS
|
|
616
638
|
scores[5].should == 0.25
|
617
639
|
scores[6].should == 0.25
|
618
640
|
end
|
619
|
-
|
641
|
+
|
620
642
|
it "Neustadtl should be sensitive to unplayed games" do
|
621
643
|
@t.player(1).find_result(1).opponent = nil
|
622
644
|
@t.player(6).find_result(1).opponent = nil
|
@@ -629,7 +651,7 @@ EOS
|
|
629
651
|
scores[5].should == 0.5 # 0.25 from Orr changed to 0.5
|
630
652
|
scores[6].should == 0.25 # loss against Fisher and unplayed against Fisher equivalent
|
631
653
|
end
|
632
|
-
|
654
|
+
|
633
655
|
it "should have correct Harkness tie break scores" do
|
634
656
|
@t.tie_breaks = ['harkness']
|
635
657
|
scores = @t.tie_break_scores
|
@@ -640,7 +662,7 @@ EOS
|
|
640
662
|
scores[5].should == 3.0
|
641
663
|
scores[6].should == 1.0
|
642
664
|
end
|
643
|
-
|
665
|
+
|
644
666
|
it "should have correct Modified Median tie break scores" do
|
645
667
|
@t.tie_breaks = ['Modified Median']
|
646
668
|
scores = @t.tie_break_scores
|
@@ -651,14 +673,14 @@ EOS
|
|
651
673
|
scores[5].should == 3.5
|
652
674
|
scores[6].should == 1.5
|
653
675
|
end
|
654
|
-
|
676
|
+
|
655
677
|
it "should have correct tie break scores for number of blacks" do
|
656
678
|
@t.tie_breaks = ['Blacks']
|
657
679
|
scores = @t.tie_break_scores
|
658
680
|
scores[3].should == 0
|
659
681
|
scores[4].should == 2
|
660
682
|
end
|
661
|
-
|
683
|
+
|
662
684
|
it "number of blacks should should be sensitive to unplayed games" do
|
663
685
|
@t.player(2).find_result(1).opponent = nil
|
664
686
|
@t.player(4).find_result(1).opponent = nil
|
@@ -667,14 +689,14 @@ EOS
|
|
667
689
|
scores[3].should == 0
|
668
690
|
scores[4].should == 1
|
669
691
|
end
|
670
|
-
|
692
|
+
|
671
693
|
it "should have correct tie break scores for number of wins" do
|
672
694
|
@t.tie_breaks = [:wins]
|
673
695
|
scores = @t.tie_break_scores
|
674
696
|
scores[1].should == 3
|
675
697
|
scores[6].should == 0
|
676
698
|
end
|
677
|
-
|
699
|
+
|
678
700
|
it "number of wins should should be sensitive to unplayed games" do
|
679
701
|
@t.player(1).find_result(1).opponent = nil
|
680
702
|
@t.player(6).find_result(1).opponent = nil
|
@@ -693,7 +715,7 @@ EOS
|
|
693
715
|
@t.player(6).rank.should == 5 # 0.5/"Ui"
|
694
716
|
@t.player(5).rank.should == 6 # 0.5/"Orr"
|
695
717
|
end
|
696
|
-
|
718
|
+
|
697
719
|
it "should be configurable to use Buchholz" do
|
698
720
|
@t.tie_breaks = ['Buchholz']
|
699
721
|
@t.rerank
|
@@ -704,7 +726,7 @@ EOS
|
|
704
726
|
@t.player(5).rank.should == 5 # 0.5/6.5
|
705
727
|
@t.player(6).rank.should == 6 # 0.5/4.5
|
706
728
|
end
|
707
|
-
|
729
|
+
|
708
730
|
it "should be configurable to use Neustadtl" do
|
709
731
|
@t.tie_breaks = [:neustadtl]
|
710
732
|
@t.rerank
|
@@ -715,7 +737,7 @@ EOS
|
|
715
737
|
@t.player(6).rank.should == 5 # 0.5/0.25/"Orr"
|
716
738
|
@t.player(5).rank.should == 6 # 0.5/0.25/"Ui"
|
717
739
|
end
|
718
|
-
|
740
|
+
|
719
741
|
it "should be configurable to use number of blacks" do
|
720
742
|
@t.tie_breaks = [:blacks]
|
721
743
|
@t.rerank
|
@@ -726,7 +748,7 @@ EOS
|
|
726
748
|
@t.player(6).rank.should == 5 # 0.5/2
|
727
749
|
@t.player(5).rank.should == 6 # 0.5/1
|
728
750
|
end
|
729
|
-
|
751
|
+
|
730
752
|
it "should be configurable to use number of wins" do
|
731
753
|
@t.tie_breaks = [:wins]
|
732
754
|
@t.rerank
|
@@ -737,13 +759,13 @@ EOS
|
|
737
759
|
@t.player(6).rank.should == 5 # 0.5/0/"Orr"
|
738
760
|
@t.player(5).rank.should == 6 # 0.5/0/"Ui"
|
739
761
|
end
|
740
|
-
|
762
|
+
|
741
763
|
it "should exhibit equivalence between Neustadtl and Sonneborn-Berger" do
|
742
764
|
@t.tie_breaks = ['Sonneborn-Berger']
|
743
765
|
@t.rerank
|
744
766
|
(1..6).inject(''){ |t,r| t << @t.player(r).rank.to_s }.should == '213465'
|
745
767
|
end
|
746
|
-
|
768
|
+
|
747
769
|
it "should be able to use more than one method" do
|
748
770
|
@t.tie_breaks = [:neustadtl, :buchholz]
|
749
771
|
@t.rerank
|
@@ -754,7 +776,7 @@ EOS
|
|
754
776
|
@t.player(5).rank.should == 5 # 0.5/0.25/6.5
|
755
777
|
@t.player(6).rank.should == 6 # 0.5/0.25/4.5
|
756
778
|
end
|
757
|
-
|
779
|
+
|
758
780
|
it "should be possible as a side effect of validation" do
|
759
781
|
@t.tie_breaks = [:buchholz]
|
760
782
|
@t.invalid(:rerank => true).should be_false
|
@@ -765,7 +787,7 @@ EOS
|
|
765
787
|
@t.player(5).rank.should == 5 # 1/6
|
766
788
|
@t.player(6).rank.should == 6 # 0/5
|
767
789
|
end
|
768
|
-
|
790
|
+
|
769
791
|
it "should be possible as a side effect of validation with multiple tie break methods" do
|
770
792
|
@t.tie_breaks = [:neustadtl, :buchholz]
|
771
793
|
@t.invalid(:rerank => true).should be_false
|