Created
December 20, 2011 05:40
-
-
Save bbasata/1500429 to your computer and use it in GitHub Desktop.
A bowling game
This file contains hidden or 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
module Enumerable | |
def sum(identity=0) | |
inject(identity) { |sum,each| sum + each } | |
end | |
end | |
class BowlingGame | |
class Frame | |
def initialize | |
@rolls = [] | |
@bonuses = [] | |
end | |
def hit(pins) | |
@rolls << pins | |
end | |
def bonus(pins) | |
@bonuses << pins | |
end | |
def open? | |
!closed? | |
end | |
def closed? | |
strike? || @rolls.size == 2 | |
end | |
def strike? | |
first_roll == 10 | |
end | |
def spare? | |
score == 10 && !strike? | |
end | |
def score | |
@rolls.sum + @bonuses.sum | |
end | |
def first_roll | |
@rolls.first | |
end | |
def waiting_for_bonus | |
(strike? && @bonuses.size < 2) || (spare? && @bonuses.size < 1) | |
end | |
end | |
def initialize | |
@frames = Array.new(10) { Frame.new } | |
end | |
def hit(pins) | |
@frames.select(&:waiting_for_bonus).each { |frame| frame.bonus(pins) } | |
current_frame.hit(pins) | |
end | |
def score | |
@frames.collect(&:score).sum | |
end | |
private | |
def current_frame | |
@frames.find(&:open?) || Frame.new | |
end | |
end | |
describe BowlingGame do | |
RSpec::Matchers.define :give_score do |expected| | |
match do |rolls| | |
rolls.flatten.reject(&:nil?).each { |roll| game.hit(roll) } | |
game.score == expected | |
end | |
end | |
let(:x) { nil } | |
let(:game) { BowlingGame.new } | |
it "scores zero for an all-gutter game" do | |
([0] * 20).should give_score(0) | |
end | |
it "scores 20 for a game of all ones" do | |
([1] * 20).should give_score(20) | |
end | |
it "scores a one-roll bonus after a spare" do | |
[5, 5, 3, 3, [0] * 16].should give_score(19) | |
end | |
context "with a strike" do | |
it "scores a two-roll bonus after a strike" do | |
[10, x, 3, 3, 3, 3, [0] * 14].should give_score(28) | |
end | |
end | |
context "perfect game" do | |
example { ([10] * 12).should give_score(300) } | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment