tournament 0.0.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,8 +1,20 @@
1
- == 0.0.1 / 2008-03-23
1
+ == 1.0.0 / 2008-03-26
2
2
 
3
- * Initial Release
3
+ * Change the pool command line script usage to make it simpler (I hope)
4
+ * Add a new report: final_four
5
+ * FIXME: Final four report assumes payouts go to 1st and 2nd and last places.
6
+ This should be configurable.
7
+
8
+ == 0.0.3 / 2008-03-23
9
+
10
+ * Bugfix the picker wrapper script. Getting used to bones/rubyforge.
4
11
 
5
12
  == 0.0.2 / 2008-03-23
6
13
 
7
14
  * Changed the picker wrapper script to ruby because it seems that
8
15
  that is what rubyforge tools expect.
16
+
17
+ == 0.0.1 / 2008-03-23
18
+
19
+ * Initial Release
20
+
data/README.txt CHANGED
@@ -19,66 +19,82 @@ basketball tournament pool.
19
19
 
20
20
  == SYNOPSIS:
21
21
 
22
- The tournament command line program is installed as 'tournament'. The library
22
+ The tournament command line program is installed as 'pool'. The library
23
23
  has the 2008 NCAA tournament pre-configured. If you were to use
24
24
  this library for the 2009 NCAA tournament, code changes would be
25
25
  necessary. FIXME (add ability to read teams from a simple configuration
26
- file).
26
+ file). For usage, just execute
27
+
28
+ pool --help
29
+
30
+ For command specific usage, execute
31
+
32
+ pool <command> --help
33
+
34
+ where <command> is one of the available commands described below. The
35
+ pool command saves state in a file called pool.yml by default. This
36
+ can be overridden in all cases by using the --save-file option.
27
37
 
28
38
  The pool manager would use this program as follows:
29
39
 
30
- 1. Choose a scoring strategy. There are various scoring strategies
31
- that could be used. The library comes pre-configured with
32
- two scoring strategies:
33
-
34
- 1. Basic scoring strategy: each correct pick is worth 2 X the round.
35
- 2. Upset favoring strategy: each correct pick is worth a
36
- base amount per round plus the seed number of the winner. As
37
- pre-configured, the base amounts per round are 3, 5, 11, 19, 30
38
- and 40 points.
40
+ 1. Choose a scoring strategy. There are various scoring strategies
41
+ that could be used. The library comes pre-configured with
42
+ two scoring strategies:
43
+ 1. Basic scoring strategy: each correct pick is worth 2 X the round.
44
+ 2. Upset favoring strategy: each correct pick is worth a
45
+ base amount per round plus the seed number of the winner. As
46
+ pre-configured, the base amounts per round are 3, 5, 11, 19, 30
47
+ and 40 points.
48
+ If your scoring strategy is not one of the above, you will have to
49
+ write a class in the Bracket class, in file lib/tournament/bracket.rb.
39
50
 
40
- If your scoring strategy is not one of the above, you will have to
41
- write a class in the Bracket class, in file lib/tournament/bracket.rb.
51
+ 2. Create a directory to hold the pool data and change to it
42
52
 
43
- 2. Initialize the pool
53
+ 3. Initialize the pool
44
54
 
45
- tournament setup pool.yml [--scoring=upset_scoring_strategy]
55
+ pool setup [--scoring=upset_scoring_strategy]
46
56
 
47
- Use the --scoring argument to change to the upset favoring
48
- strategy. If the basic strategy is ok, the --scoring argument is
49
- not required.
57
+ Use the --scoring argument to change to the upset favoring
58
+ strategy. If the basic strategy is ok, the --scoring argument is
59
+ not required.
50
60
 
51
- 3. Export a tournament entry YAML file
61
+ As mentioned above, unless overridden by using the --save-file
62
+ option, the pool will save itself to the file 'pool.yml'
52
63
 
53
- tournament bracket pool.yml tournament.yml
64
+ 3. Export a tournament entry YAML file
54
65
 
55
- 4. Create entries. You can use the included buggy GUI (see below),
56
- or edit YAML files by hand.
66
+ pool dump
57
67
 
58
- 5. Import the entry YAML files into the pool
68
+ This will save the tournament entry file as tournament.yml unless
69
+ the --entry option is used to override it.
59
70
 
60
- tournament update pool.yml --add-entry=path/to/entry.yml
71
+ 4. Create entries. You can use the included buggy GUI (see below),
72
+ or edit YAML files by hand.
61
73
 
62
- 6. As games progress, update the tournament.yml file, again using the GUI or
63
- editing the YAML file by hand. Then update the pool with the new
64
- tournament YAML file
74
+ 5. Import the entry YAML files into the pool
65
75
 
66
- tournament update pool.yml --bracket=tournament.yml
76
+ pool entry --add=path/to/entry.yml
67
77
 
68
- 7. Run reports
78
+ 6. As games progress, update the tournament.yml file, again using the GUI or
79
+ editing the YAML file by hand. Then update the pool with the new
80
+ pool YAML file
81
+
82
+ pool update
83
+
84
+ 7. Run reports
69
85
 
70
- tournament report pool.yml --type=[entry|region|leader|score]
86
+ pool report [final_four|entry|region|leader|score]
71
87
 
72
- 8. After about 22 teams are left, run a possibility report. This report will
73
- run through all the remaining ways the tournament can come out and
74
- calculate the chance to win for each player. The chance to win
75
- is defined as the percentage of possibilities that lead to that player
76
- coming out on top in the pool. With more than about 22 teams left
77
- (YMMV), this report could take months to run. FIXME (Investigate
78
- possibly using EC2 or something to spread the load around, or
79
- otherwise optimize the possibility checking algorithm)
88
+ 8. After about 22 teams are left, run a possibility report. This report will
89
+ run through all the remaining ways the tournament can come out and
90
+ calculate the chance to win for each player. The chance to win
91
+ is defined as the percentage of possibilities that lead to that player
92
+ coming out on top in the pool. With more than about 22 teams left
93
+ (YMMV), this report could take months to run. FIXME (Investigate
94
+ possibly using EC2 or something to spread the load around, or
95
+ otherwise optimize the possibility checking algorithm)
80
96
 
81
- tournament report pool.yml --type=possibility
97
+ pool report possibility
82
98
 
83
99
  == SHOES GUI:
84
100
 
@@ -90,8 +106,10 @@ Tournament::Entry object. The picker program optionally takes one
90
106
  argument, the path to a Tournament::Entry YAML file. It will open
91
107
  with the provided entry's picks pre filled in.
92
108
 
93
- The GUI may be used for keeping the NCAA tournament entry YAML file
94
- up to date.
109
+ The GUI also may be used for keeping the NCAA tournament entry YAML file
110
+ up to date:
111
+
112
+ picker tournament.yml
95
113
 
96
114
  == REQUIREMENTS:
97
115
 
data/Rakefile CHANGED
@@ -16,7 +16,7 @@ PROJ.authors = 'Douglas A. Seifert'
16
16
  PROJ.email = 'doug+rubyforge@dseifert.net'
17
17
  PROJ.url = 'http://www.dseifert.net/code/tournament'
18
18
  PROJ.rubyforge_name = 'tournament'
19
- PROJ.version = '0.0.3'
19
+ PROJ.version = '1.0.0'
20
20
  PROJ.group_id = 5863
21
21
 
22
22
  PROJ.spec_opts << '--color'
@@ -24,4 +24,7 @@ PROJ.spec_opts << '--color'
24
24
  PROJ.exclude = %w(tmp$ bak$ ~$ CVS \.svn ^pkg ^doc bin/fake bin/gui_v2.rb)
25
25
  PROJ.exclude << '^tags$'
26
26
 
27
+ PROJ.rdoc_opts = ["--line-numbers", "--inline-source"]
28
+ PROJ.rdoc_template = "tasks/jamis.rb"
29
+
27
30
  # EOF
data/bin/pool CHANGED
@@ -31,16 +31,17 @@ Main do
31
31
  end
32
32
  end
33
33
 
34
- argument('save-file') do
35
- required
34
+ option('save-file', 's') do
35
+ optional
36
36
  argument :required
37
+ default 'pool.yml'
37
38
  arity 1
38
39
  description "Save file for the pool."
39
40
  end
40
41
 
41
42
  mode('setup') do
42
43
  description "Sets up the pool the first time"
43
- option('scoring', 's') do
44
+ option('scoring', 'S') do
44
45
  optional
45
46
  argument :required
46
47
  arity 1
@@ -58,56 +59,79 @@ Main do
58
59
  end
59
60
 
60
61
  mode('update') do
61
- option('bracket', 'b') do
62
+ option('entry', 'e') do
62
63
  optional
63
64
  argument :required
65
+ default 'tournament.yml'
64
66
  arity 1
65
- description "Update the tournament bracket using supplied yaml file"
67
+ description "Update the tournament entry using supplied yaml file"
66
68
  end
67
- option('add-entry', 'a') do
69
+ def run
70
+ load_pool
71
+ tournament = YAML::load_file(params['entry'].value)
72
+ @pool.bracket = tournament.picks
73
+ save_pool
74
+ end
75
+ end
76
+
77
+ mode('entry') do
78
+ option('add', 'a') do
68
79
  optional
69
80
  argument :required
70
81
  arity -1
71
82
  description "Add an entry yaml file to the pool"
72
83
  end
84
+ option('remove', 'r') do
85
+ optional
86
+ argument :required
87
+ arity -1
88
+ description "Remove an entry by name"
89
+ end
73
90
  def run
74
91
  load_pool
75
- if params['bracket'].given?
76
- tournament = YAML::load_file(params['bracket'].value)
77
- @pool.bracket = tournament.picks
92
+ if params['add'].given?
93
+ @pool.add_entry_yaml(params['add'].value)
78
94
  save_pool
79
- elsif params['add-entry'].given?
80
- @pool.add_entry_yaml(params['add-entry'].value)
95
+ elsif params['remove'].given?
96
+ @pool.remove_by_name(params['remove'].value)
81
97
  save_pool
82
98
  else
83
- puts "Please specify bracket or add-entry"
99
+ puts "Please specify add or remove"
84
100
  print usage.to_s
85
101
  exit_warn!
86
102
  end
87
103
  end
88
104
  end
89
105
 
90
- mode('bracket') do
91
- argument('bracket-yaml') do
92
- required
93
- description "Dump the pool's bracket as an Tournament::Entry object to a yaml file."
106
+ mode('dump') do
107
+ option('entry', 'e') do
108
+ optional
109
+ argument :required
110
+ default 'tournament.yml'
111
+ description "Dump the pool entry object to a yaml file."
94
112
  end
95
113
  def run
96
114
  load_pool
97
115
  tournament = Tournament::Entry.new('Tournament', @pool.bracket, 0)
98
- File.open(params['bracket-yaml'].value, "w") do |f|
116
+ File.open(params['entry'].value, "w") do |f|
99
117
  YAML::dump(tournament, f)
100
118
  end
101
119
  end
102
120
  end
103
121
 
104
122
  mode('report') do
105
- option('type', 't') do
123
+ available_reports = Tournament::Pool.instance_methods(false).map do |name|
124
+ if idx = name.index("_report")
125
+ name[0,idx]
126
+ else
127
+ nil
128
+ end
129
+ end.compact
130
+ argument('type') do
106
131
  required
107
132
  arity 1
108
- argument :required
109
- validate {|rt| ['score', 'region', 'leader', 'possibility', 'entry'].include?(rt)}
110
- description "Which report to run, score, leader, region, possibility or entry"
133
+ validate {|rt| available_reports.include?(rt)}
134
+ description "Which report to run among #{available_reports.join(', ')}"
111
135
  end
112
136
  def run
113
137
  load_pool
@@ -115,4 +139,9 @@ Main do
115
139
  end
116
140
  end
117
141
 
142
+ def run
143
+ print usage.to_s
144
+ exit_warn!
145
+ end
146
+
118
147
  end
@@ -176,7 +176,7 @@ class Tournament::Bracket
176
176
  #num_possibilities = 0
177
177
  #shifts.size.times { |n| num_possibilities |= (1 << n) }
178
178
 
179
- puts "Checking #{num_possibilities} (#{number_of_outcomes}) possible outcomes."
179
+ #puts "Checking #{num_possibilities} (#{number_of_outcomes}) possible outcomes."
180
180
  possibility = num_possibilities - 1
181
181
  while possibility >= 0
182
182
  #puts " possibility: #{Tournament::Bracket.jbin(possibility, teams.size - 1)}"
@@ -185,9 +185,9 @@ class Tournament::Bracket
185
185
  real_poss |= (((possibility & (1 << i)) > 0 ? 1 : 0) << s)
186
186
  end
187
187
  #puts " real_poss: #{Tournament::Bracket.jbin(real_poss, teams.size - 1)}"
188
- real_possibility = winners | real_poss
189
- #puts " possibility: #{Tournament::Bracket.jbin(real_possibility, teams.size - 1)}"
190
- yield(real_possibility)
188
+ real_poss = winners | real_poss
189
+ #puts " real_poss: #{Tournament::Bracket.jbin(real_poss, teams.size - 1)}"
190
+ yield(real_poss)
191
191
  possibility -= 1
192
192
  end
193
193
  end
@@ -32,6 +32,14 @@ class Tournament::Pool
32
32
  @entries << YAML::load_file(yaml)
33
33
  end
34
34
 
35
+ # Remove an entry by name from the pool
36
+ def remove_by_name(name)
37
+ entry = @entries.find {|e| e.name == name}
38
+ if !entry.nil?
39
+ @entries.delete(entry)
40
+ end
41
+ end
42
+
35
43
  # Creates a bracket for the pool by combining all the
36
44
  # regions into one bracket of 64 teams. By default the
37
45
  # bracket uses the basic scoring strategy.
@@ -289,7 +297,38 @@ class Tournament::Pool
289
297
  end
290
298
  end
291
299
 
300
+ def final_four_report
301
+ if @entries.size == 0
302
+ puts "There are no entries in the pool."
303
+ return
304
+ end
305
+ if self.bracket.teams_left != 4
306
+ puts "The final four report should only be run when there"
307
+ puts "are exactly four teams left in the tournament."
308
+ return
309
+ end
310
+ print "Final Four: #{self.bracket.winners[4][0,2].map{|t| "(#{t.seed}) #{t.name}"}.join(" vs. ")}"
311
+ puts " #{self.bracket.winners[4][2,2].map{|t| "(#{t.seed}) #{t.name}"}.join(" vs. ")}"
312
+ sep= "--------------+----------------+----------------------------"
313
+ puts " Championship | Champion | Winners"
314
+ puts sep
315
+ self.bracket.each_possible_bracket do |poss|
316
+ rankings = @entries.map{|p| [p, p.picks.score_against(poss)] }.sort_by {|arr| -arr[1] }
317
+ first = rankings[0][0]
318
+ second = rankings[1][0]
319
+ last = rankings[-1][0]
320
+ puts "%14s|%16s|%s" % [poss.winners[5].map{|t| t.short_name}.join("-"),
321
+ poss.champion.name, " 1: #{first.name} (#{rankings[0][1]})"]
322
+ puts "%14s|%16s|%s" % ['', '',
323
+ " 2: #{second.name} (#{rankings[1][1]})"]
324
+ puts "%14s|%16s|%s" % ['', '',
325
+ "LAST: #{last.name} (#{rankings[-1][1]})"]
326
+ puts sep
327
+ end
328
+ end
329
+
292
330
  def possibility_report
331
+ $stdout.sync = true
293
332
  if @entries.size == 0
294
333
  puts "There are no entries in the pool."
295
334
  return
@@ -298,6 +337,9 @@ class Tournament::Pool
298
337
  min_ranking = @entries.map{|p| @entries.size + 1}
299
338
  times_winner = @entries.map{|p| 0 }
300
339
  count = 0
340
+ old_percentage = -1
341
+ old_remaining = 1_000_000_000_000
342
+ puts "Checking #{self.bracket.number_of_outcomes} possible outcomes"
301
343
  start = Time.now.to_f
302
344
  self.bracket.each_possible_bracket do |poss|
303
345
  poss_scores = @entries.map{|p| p.picks.score_against(poss)}
@@ -310,15 +352,15 @@ class Tournament::Pool
310
352
  times_winner[i] += 1 if rank == 1
311
353
  end
312
354
  count += 1
313
- percentage = (count * 100 / self.bracket.number_of_outcomes) * 1000
314
- if (percentage % 1000) == 0
315
- percentage /= 1000
316
- hashes = '#' * percentage + '>'
317
- elapsed = Time.now.to_f - start
318
- spp = elapsed / count
319
- remaining = ((self.bracket.number_of_outcomes - count) * spp).to_i
320
- print "\rCalculating: %3d%% +#{hashes.ljust(100, '-')}+ %5d seconds remaining" % [percentage, remaining]
321
-
355
+ percentage = (count * 100.0 / self.bracket.number_of_outcomes)
356
+ elapsed = Time.now.to_f - start
357
+ spp = elapsed / count
358
+ remaining = ((self.bracket.number_of_outcomes - count) * spp).to_i
359
+ if (percentage.to_i != old_percentage) || (remaining < old_remaining)
360
+ old_remaining = remaining
361
+ old_percentage = percentage.to_i
362
+ hashes = '#' * (percentage.to_i/5) + '>'
363
+ print "\rCalculating: %3d%% +#{hashes.ljust(20, '-')}+ %5d seconds remaining" % [percentage.to_i, remaining]
322
364
  end
323
365
  end
324
366
  puts "\n"
data/tasks/doc.rake CHANGED
@@ -8,6 +8,7 @@ namespace :doc do
8
8
  Rake::RDocTask.new do |rd|
9
9
  rd.main = PROJ.rdoc_main
10
10
  rd.rdoc_dir = PROJ.rdoc_dir
11
+ rd.template = PROJ.rdoc_template if PROJ.rdoc_template
11
12
 
12
13
  incl = Regexp.new(PROJ.rdoc_include.join('|'))
13
14
  excl = Regexp.new(PROJ.rdoc_exclude.join('|'))
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tournament
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Douglas A. Seifert
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-03-23 00:00:00 -07:00
12
+ date: 2008-03-26 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -70,6 +70,8 @@ has_rdoc: true
70
70
  homepage: http://www.dseifert.net/code/tournament
71
71
  post_install_message:
72
72
  rdoc_options:
73
+ - --line-numbers
74
+ - --inline-source
73
75
  - --main
74
76
  - README.txt
75
77
  require_paths: