icu_tournament 1.0.1 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/icu_tournament/tournament_sp.rb +40 -17
- data/lib/icu_tournament/version.rb +1 -1
- data/spec/tournament_sp_spec.rb +72 -24
- metadata +2 -2
@@ -23,6 +23,17 @@ information.
|
|
23
23
|
tournament = parser.parse_file('champs', "2010-07-03") # looks for "champs.ini", "champs.trn" and "champs.sco"
|
24
24
|
puts parser.error unless tournament
|
25
25
|
|
26
|
+
By default, the parser extracts local ratings and IDs from the SwissPerfect files. If instead international
|
27
|
+
ratings or IDs are required, use the options _id_ and _rating_. For example:
|
28
|
+
|
29
|
+
tournament = parser.parse_file('ncc', "2010-05-08")
|
30
|
+
tournament.player(2).id # => 12379 (ICU ID)
|
31
|
+
tournament.player(2).rating # => 2556 (ICU rating)
|
32
|
+
|
33
|
+
tournament = parser.parse_file('ncc', "2010-05-08", :id => :intl, :rating => :intl)
|
34
|
+
tournament.player(2).id # => 1205064 (FIDE ID)
|
35
|
+
tournament.player(2).rating # => 2530 (FIDE rating)
|
36
|
+
|
26
37
|
Because the data is in three parts, some of which are in a legacy binary format, serialization to this format is
|
27
38
|
not supported. Instead, a method is provided to serialize any tournament text in the format of <em>SwissPerfects</em>
|
28
39
|
text export format, an example of which is shown below.
|
@@ -39,16 +50,28 @@ implementation of the ICU ratings database.
|
|
39
50
|
|
40
51
|
swiss_perfect = tournament.serialize('SwissPerfect')
|
41
52
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
53
|
+
The order of players in the serialized output is always by player number and as a side effect of serialization,
|
54
|
+
the player numbers will be adjusted to ensure they range from 1 to the total number of players (i.e. renumbered
|
55
|
+
in order). If you would prefer rank-order instead, then you must first renumber the players by rank (the default
|
56
|
+
renumbering method) before serializing. For example:
|
57
|
+
|
58
|
+
swiss_perfect = tournament.renumber.serialize('SwissPerfect')
|
59
|
+
|
60
|
+
There should be no need to explicitly rank the tournament first, as that information is already present in
|
61
|
+
SwissPerfect files (i.e. each player should already have a rank after the files have been parsed).
|
62
|
+
Additionally, the tie break rules used for the tournament will be available from:
|
63
|
+
|
64
|
+
tournament.tie_breaks # => [:buchholz, :harkness]
|
65
|
+
|
66
|
+
Should you wish to rank the tournament using a different set of tie-break rules, you can do something like the following:
|
46
67
|
|
47
|
-
|
68
|
+
tournament.tie_breaks = [:wins, :blacks]
|
69
|
+
swiss_perfect = tournament.rerank.renumber.serialize('SwissPerfect')
|
48
70
|
|
49
71
|
== Todo
|
50
72
|
|
51
73
|
* Allow parsing from 1 zip file
|
74
|
+
* Implement the extra tie-break rules that SP has
|
52
75
|
|
53
76
|
=end
|
54
77
|
|
@@ -70,13 +93,13 @@ without the option argument (which will renumber by rank) before serializing. Fo
|
|
70
93
|
SCO = %w{ROUND WHITE BLACK W_SCORE B_SCORE W_TYPE B_TYPE} # not used W_SUBSCO, B_SUBSCO
|
71
94
|
|
72
95
|
# Parse SP data returning a Tournament or raising an exception on error.
|
73
|
-
def parse_file!(file, start)
|
96
|
+
def parse_file!(file, start, arg={})
|
74
97
|
@t = Tournament.new('Dummy', start)
|
75
98
|
@bonus = {}
|
76
99
|
@start_no = {}
|
77
100
|
ini, trn, sco = get_files(file)
|
78
101
|
parse_ini(ini)
|
79
|
-
parse_trn(trn)
|
102
|
+
parse_trn(trn, arg)
|
80
103
|
parse_sco(sco)
|
81
104
|
fixup
|
82
105
|
@t.validate!(:rerank => true)
|
@@ -85,9 +108,9 @@ without the option argument (which will renumber by rank) before serializing. Fo
|
|
85
108
|
|
86
109
|
# Parse SP data returning an ICU::Tournament or a nil on failure. In the latter
|
87
110
|
# case, an error message will be available via the <em>error</em> method.
|
88
|
-
def parse_file(file, start)
|
111
|
+
def parse_file(file, start, arg={})
|
89
112
|
begin
|
90
|
-
parse_file!(file, start)
|
113
|
+
parse_file!(file, start, arg)
|
91
114
|
rescue => ex
|
92
115
|
@error = ex.message
|
93
116
|
nil
|
@@ -168,7 +191,7 @@ without the option argument (which will renumber by rank) before serializing. Fo
|
|
168
191
|
end.find_all { |tb| tb }
|
169
192
|
end
|
170
193
|
|
171
|
-
def parse_trn(file)
|
194
|
+
def parse_trn(file, arg={})
|
172
195
|
begin
|
173
196
|
trn = DBF::Table.new(file)
|
174
197
|
rescue
|
@@ -177,7 +200,7 @@ without the option argument (which will renumber by rank) before serializing. Fo
|
|
177
200
|
raise "invalid TRN file (no records)" if trn.record_count == 0
|
178
201
|
trn.each do |r|
|
179
202
|
next unless r
|
180
|
-
h = trn_record_to_hash(r)
|
203
|
+
h = trn_record_to_hash(r, arg)
|
181
204
|
@t.add_player(ICU::Player.new(h.delete(:first_name), h.delete(:last_name), h.delete(:num), h))
|
182
205
|
end
|
183
206
|
end
|
@@ -196,18 +219,18 @@ without the option argument (which will renumber by rank) before serializing. Fo
|
|
196
219
|
end
|
197
220
|
end
|
198
221
|
|
199
|
-
def trn_record_to_hash(r)
|
222
|
+
def trn_record_to_hash(r, arg={})
|
200
223
|
@bonus[r.attributes["ID"]] = %w{BONUS MEMO}.inject(0.0){ |b,k| b > 0.0 ? b : r.attributes[k].to_f }
|
201
224
|
@start_no[r.attributes["ID"]] = r.attributes["START_NO"]
|
202
225
|
TRN.inject(Hash.new) do |hash, pair|
|
203
|
-
|
204
|
-
|
205
|
-
val
|
226
|
+
key = pair[1]
|
227
|
+
key = key[arg[pair[0]].to_s == 'intl' ? 1 : 0] if key.class == Array
|
228
|
+
val = r.attributes[key]
|
206
229
|
case pair[0]
|
207
230
|
when :fed then val = val && val.match(/^[A-Z]{3}$/i) ? val.upcase : nil
|
208
231
|
when :gender then val = val.to_i > 0 ? %w(M F)[val.to_i-1] : nil
|
209
|
-
when :id then val = val.to_i > 0 ? val :
|
210
|
-
when :rating then val = val.to_i > 0 ? val :
|
232
|
+
when :id then val = val.to_i > 0 ? val : nil
|
233
|
+
when :rating then val = val.to_i > 0 ? val : nil
|
211
234
|
when :title then val = val.to_i > 0 ? %w(GM WGM IM WIM FM WFM)[val.to_i-1] : nil
|
212
235
|
end
|
213
236
|
hash[pair[0]] = val unless val.nil? || val == ''
|
data/spec/tournament_sp_spec.rb
CHANGED
@@ -10,7 +10,7 @@ module ICU
|
|
10
10
|
class Player
|
11
11
|
def signature
|
12
12
|
[
|
13
|
-
name, id, rating, points,
|
13
|
+
name, id, rating, points, rank,
|
14
14
|
results.map{ |r| r.round }.join(''),
|
15
15
|
results.map{ |r| r.score }.join(''),
|
16
16
|
results.map{ |r| r.colour || "-" }.join(''),
|
@@ -38,10 +38,14 @@ module ICU
|
|
38
38
|
end
|
39
39
|
|
40
40
|
it "should have correct details for selected players" do
|
41
|
-
@t.player(2).signature.should == "Mullooly, Neil M.|6438|1083|6.0|123456|WWWWWW|WBWBWB|TTTTTT" # winner
|
42
|
-
@t.player(4).signature.should == "Gallagher, Mark|12138|1036|4.0|123456|WLWWWL|WBWBWB|FTTTTT" # had one bye
|
43
|
-
@t.player(45).signature.should == "Catre, Loredan||507|3.5|123456|WDLWLW|BWBWBW|FTTTFT" # had two byes
|
44
|
-
@t.player(56).signature.should == "McDonnell, Cathal||498|0.0|1|L|-|F" # last
|
41
|
+
@t.player(2).signature.should == "Mullooly, Neil M.|6438|1083|6.0|1|123456|WWWWWW|WBWBWB|TTTTTT" # winner
|
42
|
+
@t.player(4).signature.should == "Gallagher, Mark|12138|1036|4.0|9|123456|WLWWWL|WBWBWB|FTTTTT" # had one bye
|
43
|
+
@t.player(45).signature.should == "Catre, Loredan||507|3.5|18|123456|WDLWLW|BWBWBW|FTTTFT" # had two byes
|
44
|
+
@t.player(56).signature.should == "McDonnell, Cathal||498|0.0|54|1|L|-|F" # last
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should have consistent ranks" do
|
48
|
+
@t.players.map{ |p| p.rank }.sort.join('').should == (1..@t.players.size).to_a.join('')
|
45
49
|
end
|
46
50
|
|
47
51
|
it "should have the correct tie breaks" do
|
@@ -67,10 +71,14 @@ module ICU
|
|
67
71
|
end
|
68
72
|
|
69
73
|
it "should have correct details for selected players" do
|
70
|
-
@t.player(1).signature.should == "Griffiths, Ryan-Rhys|6897|2225|3.0|123|WWW|WWB|TTT"
|
71
|
-
@t.player(2).signature.should == "Flynn, Jamie|5226|1633|2.0|123|WLW|WBW|TTT"
|
72
|
-
@t.player(3).signature.should == "Hulleman, Leon|6409|1466|1.0|123|LWL|BBW|TTT"
|
73
|
-
@t.player(4).signature.should == "Dunne, Thomas|10914||0.0|123|LLL|BWB|TTT"
|
74
|
+
@t.player(1).signature.should == "Griffiths, Ryan-Rhys|6897|2225|3.0|1|123|WWW|WWB|TTT"
|
75
|
+
@t.player(2).signature.should == "Flynn, Jamie|5226|1633|2.0|2|123|WLW|WBW|TTT"
|
76
|
+
@t.player(3).signature.should == "Hulleman, Leon|6409|1466|1.0|3|123|LWL|BBW|TTT"
|
77
|
+
@t.player(4).signature.should == "Dunne, Thomas|10914||0.0|4|123|LLL|BWB|TTT"
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should have consistent ranks" do
|
81
|
+
@t.players.map{ |p| p.rank }.sort.join('').should == (1..@t.players.size).to_a.join('')
|
74
82
|
end
|
75
83
|
|
76
84
|
it "should have the no tie breaks" do
|
@@ -95,12 +103,16 @@ module ICU
|
|
95
103
|
end
|
96
104
|
|
97
105
|
it "should have correct details for selected players" do
|
98
|
-
@t.player(15).signature.should == "Talazec, Laurent|10692|1570|5.5|1234567|WWWDDDW|WWBWBWB|FTTTTTT" # winner
|
99
|
-
@t.player(6).signature.should == "Foenander, Phillip|7168|1434|4.0|1234567|WLWLLWW|BWBWBWB|TTFFTTT" # had some byes
|
100
|
-
@t.player(19).signature.should == "Wall, Robert|||3.0|34567|WWLWL|WWBBW|FTTTT" # didn't play 1st 2 rounds
|
101
|
-
@t.player(17).signature.should == "Freeman, Conor|||2.0|1234567|DDLWLLL|--BWBWB|FFTTTTT" # had byes and bonus (in BONUS)
|
102
|
-
@t.player(18).signature.should == "Freeman, Ruiri|||2.0|1234567|DDLLLLW|--WBBWB|FFTTTTF" # had byes and bonus (in BONUS)
|
103
|
-
@t.player(16).signature.should == "O'Connor, David|||1.0|123|WLL|WBW|FTF" # last
|
106
|
+
@t.player(15).signature.should == "Talazec, Laurent|10692|1570|5.5|1|1234567|WWWDDDW|WWBWBWB|FTTTTTT" # winner
|
107
|
+
@t.player(6).signature.should == "Foenander, Phillip|7168|1434|4.0|7|1234567|WLWLLWW|BWBWBWB|TTFFTTT" # had some byes
|
108
|
+
@t.player(19).signature.should == "Wall, Robert|||3.0|14|34567|WWLWL|WWBBW|FTTTT" # didn't play 1st 2 rounds
|
109
|
+
@t.player(17).signature.should == "Freeman, Conor|||2.0|16|1234567|DDLWLLL|--BWBWB|FFTTTTT" # had byes and bonus (in BONUS)
|
110
|
+
@t.player(18).signature.should == "Freeman, Ruiri|||2.0|17|1234567|DDLLLLW|--WBBWB|FFTTTTF" # had byes and bonus (in BONUS)
|
111
|
+
@t.player(16).signature.should == "O'Connor, David|||1.0|19|123|WLL|WBW|FTF" # last
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should have consistent ranks" do
|
115
|
+
@t.players.map{ |p| p.rank }.sort.join('').should == (1..@t.players.size).to_a.join('')
|
104
116
|
end
|
105
117
|
|
106
118
|
it "should have the correct tie breaks" do
|
@@ -121,10 +133,14 @@ module ICU
|
|
121
133
|
end
|
122
134
|
|
123
135
|
it "should have correct details for selected players" do
|
124
|
-
@t.player(15).signature.should == "Gupta, Radhika||1247|3.0|123|WWW|BBW|TTT" # won all his games
|
125
|
-
@t.player(18).signature.should == "Hurley, Thomas|6292|820|1.0|1|W|B|F" # scored just 1 from a bye in R1
|
126
|
-
@t.player(8).signature.should == "Berney, Mark|10328|1948|2.0|23|WW|BW|TT" # didn't play in round 1
|
127
|
-
@t.player(10).signature.should == "O'Donnell, Conor E.|10792|1073|2.0|123|LWW|WBW|TFT" # got just 1 point for a bye
|
136
|
+
@t.player(15).signature.should == "Gupta, Radhika||1247|3.0|1|123|WWW|BBW|TTT" # won all his games
|
137
|
+
@t.player(18).signature.should == "Hurley, Thomas|6292|820|1.0|14|1|W|B|F" # scored just 1 from a bye in R1
|
138
|
+
@t.player(8).signature.should == "Berney, Mark|10328|1948|2.0|3|23|WW|BW|TT" # didn't play in round 1
|
139
|
+
@t.player(10).signature.should == "O'Donnell, Conor E.|10792|1073|2.0|10|123|LWW|WBW|TFT" # got just 1 point for a bye
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should have consistent ranks" do
|
143
|
+
@t.players.map{ |p| p.rank }.sort.join('').should == (1..@t.players.size).to_a.join('')
|
128
144
|
end
|
129
145
|
|
130
146
|
it "should have the correct tie breaks" do
|
@@ -145,11 +161,43 @@ module ICU
|
|
145
161
|
end
|
146
162
|
|
147
163
|
it "should have correct details for selection of players who got bonuses (in MEMO)" do
|
148
|
-
@t.player(23).signature.should == "Long, Killian|10293|1506|2.5|123456|WDLLWL|WWBWBB|TFTTTT"
|
149
|
-
@t.player(26).signature.should == "Bradley, Michael|6756|1413|3.0|123456|DDLWWL|BWWBWW|TFTTTT"
|
150
|
-
@t.player(15).signature.should == "Twomey, Pat|1637|1656|4.5|123456|WDLWWW|WWWBWB|FFTTTT"
|
151
|
-
@t.player(46).signature.should == "O'Riordan, Pat|10696|900|2.0|123456|LDDLDD|BWBWWB|TTTTFT"
|
152
|
-
@t.player(38).signature.should == "Gill, Craig I.|10637|1081|2.0|123456|LLWDDL|BWBWWB|TTTTFT"
|
164
|
+
@t.player(23).signature.should == "Long, Killian|10293|1506|2.5|33|123456|WDLLWL|WWBWBB|TFTTTT"
|
165
|
+
@t.player(26).signature.should == "Bradley, Michael|6756|1413|3.0|26|123456|DDLWWL|BWWBWW|TFTTTT"
|
166
|
+
@t.player(15).signature.should == "Twomey, Pat|1637|1656|4.5|7|123456|WDLWWW|WWWBWB|FFTTTT"
|
167
|
+
@t.player(46).signature.should == "O'Riordan, Pat|10696|900|2.0|42|123456|LDDLDD|BWBWWB|TTTTFT"
|
168
|
+
@t.player(38).signature.should == "Gill, Craig I.|10637|1081|2.0|43|123456|LLWDDL|BWBWWB|TTTTFT"
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should have consistent ranks" do
|
172
|
+
@t.players.map{ |p| p.rank }.sort.join('').should == (1..@t.players.size).to_a.join('')
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
context "National Club Champiomships 2010" do
|
177
|
+
|
178
|
+
before(:all) do
|
179
|
+
@p = ICU::Tournament::SwissPerfect.new
|
180
|
+
@t = @p.parse_file(SAMPLES + 'ncc', "2010-05-08")
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should parse and have the right basic details" do
|
184
|
+
@p.error.should be_nil
|
185
|
+
@t.signature.should == "National Club Championship 2010|Gerry Graham|4|2010-05-08|77"
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should have correct details for selection of players, including ICU IDs" do
|
189
|
+
@t.player(2).signature.should == "Szabo, Gergely|12379|2530|4.0|4|1234|WWWW|WBWB|TTTT"
|
190
|
+
@t.player(5).signature.should == "Daly, Colm|295|2314|3.5|7|1234|WWWD|WBWB|TTTT"
|
191
|
+
@t.player(8).signature.should == "Vega, Marcos Llaneza||2475|3.0|16|1234|DDWW|BWBW|TTTT"
|
192
|
+
@t.player(67).signature.should == "Lee, Shane|780|1633|1.0|52|134|DLD|WWW|TTT"
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should have correct details for selection of players, including international IDs and ratings when so configured" do
|
196
|
+
@t = @p.parse_file(SAMPLES + 'ncc', "2010-05-08", :id => :intl, :rating => :intl)
|
197
|
+
@t.player(2).signature.should == "Szabo, Gergely|1205064||4.0|4|1234|WWWW|WBWB|TTTT"
|
198
|
+
@t.player(5).signature.should == "Daly, Colm|2500434||3.5|7|1234|WWWD|WBWB|TTTT"
|
199
|
+
@t.player(8).signature.should == "Vega, Marcos Llaneza|2253585||3.0|16|1234|DDWW|BWBW|TTTT"
|
200
|
+
@t.player(67).signature.should == "Lee, Shane|||1.0|52|134|DLD|WWW|TTT"
|
153
201
|
end
|
154
202
|
end
|
155
203
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: icu_tournament
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Orr
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-05-
|
12
|
+
date: 2010-05-20 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|