Created
July 10, 2014 05:33
-
-
Save fj/39c3462fa25fe187ca69 to your computer and use it in GitHub Desktop.
My work on the Uncle Bob bowling kata.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Game | |
def roll(*pins) | |
(@rolls ||= []).push *pins | |
end | |
def score | |
scores.inject(:+) | |
end | |
def scores | |
[].tap do |frame_scores| | |
10.times do | |
score, taken = score_frame(@rolls) | |
@rolls = @rolls.drop(taken) | |
frame_scores << score | |
end | |
end | |
end | |
def score_frame(rolls) | |
rolls_for_scoring, rolls_in_this_frame = case frame_kind(rolls) | |
when :strike then [3, 1] | |
when :spare then [3, 2] | |
when :open then [2, 2] | |
end | |
[rolls.take(rolls_for_scoring).inject(:+), rolls_in_this_frame] | |
end | |
def frame_kind(rolls) | |
first, second = rolls | |
return :strike if first == 10 | |
return :spare if first + second == 10 | |
return :open | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
require 'lib/game' | |
describe Game do | |
let(:game) { described_class.new } | |
def roll(*rolls) | |
game.roll(*rolls.flatten) | |
end | |
def frames(n, frame = [0, 0]) | |
Array.new(n, frame) | |
end | |
it "scores twelve strikes as 300" do | |
roll frames(12, [10]) | |
expect(game.score).to eq 300 | |
end | |
it "scores ten gutter frames as 0" do | |
roll frames(10) | |
expect(game.score).to eq 0 | |
end | |
it "scores ten open frames as their sums" do | |
roll frames(10, [2, 3]) | |
expect(game.score).to eq 50 | |
end | |
it "scores a spare as 10 plus next roll" do | |
roll 4, 6, 7, 3, frames(8) | |
expect(game.scores.first).to eq 17 | |
end | |
it "scores a strike as 10 plus next two rolls" do | |
roll 10, 4, 6, 7, 3, frames(7) | |
expect(game.scores.first).to eq 20 | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment