/
Rakefile
111 lines (89 loc) · 2.05 KB
/
Rakefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
require "rspec/core/rake_task"
require "method_source"
require_relative "lib/golf"
RSpec::Core::RakeTask.new(:rspec)
task :default => [:check_version, :specs, :score]
task :check_version do
fail "Please run using Ruby 1.9.3" unless RUBY_VERSION == "1.9.3"
end
task :specs do
begin
Rake::Task[:rspec].invoke
rescue RuntimeError
end
end
task :score do
Scorer.new(File.expand_path("../spec_output.txt", __FILE__)).print_scores
end
class Scorer
def initialize file
spec_output = File.read file
number_of_holes = spec_output.lines.grep(/^ \.hole_\d+$/).count
@holes = (1..number_of_holes).map {|n| Hole.score n, spec_output }
end
def print_scores
puts <<-EOF
+--------+---------+---------+
| Hole | Shots | Total |
+--------+---------+---------+
EOF
@holes.inject(Total.new) do |total, hole|
total << hole
hole.print total
puts " +--------+---------+---------+\n"
total
end
end
end
class Hole
class Failed
def initialize number
@number = number
end
def success?
false
end
def print total_so_far
puts " | %2d | Failed | %4s |" % [@number, total_so_far]
end
end
attr_reader :score
def initialize number
@number = number
calculate_score
end
def success?
true
end
def self.score number, spec_output
completed?(number, spec_output) ? new(number) : Failed.new(number)
end
def self.completed? number, spec_output
spec_output !~ /^\s*\d+\) Golf.hole_#{number}\s/
end
def print total_so_far
puts " | %2d | %3d | %4s |" % [@number, @score, total_so_far]
end
private
def calculate_score
method = Golf.method :"hole_#{@number}"
lines = method.source.split(/[\;\n]/)[1..-2].map &:strip
@score = lines.join.length
end
end
class Total
def initialize
@still_playing = true
@score = 0
end
def << hole
if hole.success?
@score += hole.score
else
@still_playing = false
end
end
def to_s
@still_playing ? @score.to_s : "----"
end
end