Skip to content

Instantly share code, notes, and snippets.

@jackboberg
Last active August 29, 2015 13:59
Show Gist options
  • Select an option

  • Save jackboberg/10987723 to your computer and use it in GitHub Desktop.

Select an option

Save jackboberg/10987723 to your computer and use it in GitHub Desktop.
module Bowling
class Frame
attr_reader :rolls
def initialize
@rolls = []
end
def pins
@rolls.inject { |sum,x| sum + x } || 0
end
def roll(pins=0)
@rolls << pins
end
def strike?
@rolls.size == 1 and pins == 10
end
def spare?
@rolls.size == 2 and pins == 10
end
def complete?
@rolls.size == 2 or strike?
end
def score
# pins + next rolls if strike? or spare?
# may need to pass frames as arg to lookup
end
end
end
module Bowling
class Game
def initialize
@frames = []
new_frame
end
def roll pins=0
@current_frame.roll pins
new_frame if @current_frame.complete?
end
def new_frame
@frames << Bowling::Frame.new
@current_frame = @frames.last
end
def play rolls
rolls.each { |r| roll(r) }
end
def score
# each of first 10 frames score
# 11 & 12 psuedo frames for scoring final spare/strikes
end
end
end
require "bowling/frame"
require "bowling/game"
module Bowling
end
require 'rspec'
require 'bowling'
describe Bowling::Frame do
subject(:frame) { Bowling::Frame.new }
its(:rolls) { should be_a(Array) }
describe ':pins' do
its(:pins) { should be(0) }
it 'increments when rolled' do
expect { frame.roll(1) }.to change{frame.pins}.by(1)
end
end
describe ':complete?' do
context 'after first roll' do
before { frame.roll }
its(:complete?) { should be_false }
context 'with a strike' do
before { allow(frame).to receive(:strike?).and_return(true) }
its(:complete?) { should be_true }
end
end
context 'on second roll' do
before { 2.times { frame.roll } }
its(:complete?) { should be_true }
end
end
describe ':strike?' do
its(:strike?) { should be_false }
context 'with 10 pins on first roll' do
before { frame.roll(10) }
its(:strike?) { should be_true }
end
context 'with 10 pins on second roll' do
before do
frame.roll(0)
frame.roll(10)
end
its(:strike?) { should be_false }
end
end
describe ':spare?' do
its(:spare?) { should be_false }
context 'with 10 pins on first roll' do
before { frame.roll(10) }
its(:spare?) { should be_false }
end
context 'with 10 pins on second roll' do
before do
frame.roll(0)
frame.roll(10)
end
its(:spare?) { should be_true }
end
end
pending ':score'
end
require 'rspec'
require 'bowling'
describe Bowling::Game do
subject(:game) { Bowling::Game.new }
let(:rolls) { Array.new(20, 1) }
describe ':play' do
it 'calls :roll for each roll' do
expect(game).to receive(:roll).exactly(rolls.size).times
game.play rolls
end
end
describe ':roll' do
let(:frame) { Bowling::Frame.new }
before { game.instance_variable_set :@current_frame, frame }
it 'passes the number of pins to the current frame' do
expect(frame).to receive(:roll).with(1)
game.roll 1
end
context 'when frame not complete' do
before { allow(frame).to receive(:complete?).and_return(false) }
it 'does not advance frame' do
expect(game).not_to receive(:new_frame)
game.roll 1
end
end
context 'when frame complete' do
before { allow(frame).to receive(:complete?).and_return(true) }
it 'advances frame' do
expect(game).to receive(:new_frame)
game.roll 1
end
end
end
describe ':new_frame' do
let(:frame) { Bowling::Frame.new }
before { game.instance_variable_set :@current_frame, frame }
it 'generates a new frame' do
expect { game.new_frame }.to change { game.instance_variable_get(:@frames).size }.by(1)
end
it 'sets the new frame as current' do
game.new_frame
expect(game.instance_variable_get(:@current_frame)).not_to eql(frame)
end
end
pending ':score'
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment