icu_tournament 1.0.1 → 1.0.3
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_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
|