Skip to content

Instantly share code, notes, and snippets.

@kevbuchanan
Last active December 23, 2015 07:49
Show Gist options
  • Save kevbuchanan/6603426 to your computer and use it in GitHub Desktop.
Save kevbuchanan/6603426 to your computer and use it in GitHub Desktop.
class Frame
attr_reader :rolls
def initialize(rolls)
@rolls = rolls.first == 10 ? [rolls.first] : rolls
end
def roll_score
@rolls.inject(:+)
end
def spare?
roll_score == 10 && !strike?
end
def strike?
@rolls.first == 10
end
def bonus_rolls
if strike?
2
elsif spare?
1
else
0
end
end
def first_roll
if strike?
"X"
elsif @rolls.first == 0
"-"
else
@rolls.first.to_s
end
end
def last_roll
if strike?
""
elsif spare?
"/"
elsif @rolls.last == 0
"-"
else
@rolls.last.to_s
end
end
end
class Scorecard
attr_reader :bowler
def initialize(input)
@bowler = input.split(' ')[0]
@rolls = input.split(' ')[1..-1].map(&:to_i)
@frames = generate_frames
end
def total_score
(0..9).inject(0) do |score, index|
score += score_for(index)
end
end
def score_for(frame_index)
frame = @frames[frame_index]
next_frames_rolls = []
next_frames_rolls += @frames[frame_index + 1].rolls unless @frames[frame_index + 1].nil?
next_frames_rolls += @frames[frame_index + 2].rolls unless @frames[frame_index + 2].nil?
extra_score = next_frames_rolls.shift(frame.bonus_rolls).inject(:+) || 0
frame.roll_score + extra_score
end
def generate_frames
frames = []
new_rolls = @rolls.join(' ').gsub('10', '10 0').split(' ').map(&:to_i)
new_rolls.each_slice(2) do |frame|
frames << Frame.new(frame)
end
frames
end
def print_scorecard
puts "#{@bowler}'s score: #{total_score}"
puts "Frame Roll Roll Score"
@frames.each_with_index do |frame, index|
puts "#{index + 1} #{frame.first_roll} #{frame.last_roll} #{score_for(index)}"
end
end
end
scorecard = Scorecard.new('John 6 2 7 1 10 9 0 8 2 10 10 3 5 7 2 5 5 8')
scorecard.print_scorecard
require 'rspec'
require 'shoulda'
require_relative "bowling"
describe Frame do
let(:frame) { Frame.new([0,9]) }
let(:other_frame) { Frame.new([5,0]) }
let(:strike_frame) { Frame.new([10, 0]) }
let(:spare_frame) { Frame.new([7, 3]) }
it 'should have a rolls array' do
expect(frame.rolls).to eq([0,9])
end
it 'should remove the 0 roll from a strike roll' do
expect(strike_frame.rolls).to eq([10])
end
describe '#roll_score' do
it 'should return the sum of the two rolls' do
expect(frame.roll_score).to eq(9)
end
end
describe '#spare?' do
context 'a spare' do
it 'should return true' do
expect(spare_frame.spare?).to be_true
end
end
context 'not a spare' do
it 'should return false' do
expect(frame.spare?).to be_false
end
end
end
describe '#strike?' do
context 'a strike' do
it 'should return true' do
expect(strike_frame.strike?).to be_true
end
end
context 'not a strike' do
it 'should return false' do
expect(frame.strike?).to be_false
end
end
end
describe '#bonus_rolls' do
context 'a strike' do
it 'should return 2' do
expect(strike_frame.bonus_rolls).to eq(2)
end
end
context 'a spare' do
it 'should return 1' do
expect(spare_frame.bonus_rolls).to eq(1)
end
end
context 'not a spare or strike' do
it 'should return 0' do
expect(frame.bonus_rolls).to eq(0)
end
end
end
describe '#first_roll' do
context 'a strike' do
it 'should return a X' do
expect(strike_frame.first_roll).to eq('X')
end
end
context 'a zero' do
it 'should return a -' do
expect(frame.first_roll).to eq('-')
end
end
context 'any other roll' do
it 'should return the number' do
expect(spare_frame.first_roll).to eq('7')
end
end
end
describe '#last_roll' do
context 'a strike' do
it 'should return an empty string' do
expect(strike_frame.last_roll).to eq('')
end
end
context 'a spare' do
it 'should return a /' do
expect(spare_frame.last_roll).to eq('/')
end
end
context 'a zero' do
it 'should return a -' do
expect(other_frame.last_roll).to eq('-')
end
end
context 'any other roll' do
it 'should return the number' do
expect(frame.last_roll).to eq('9')
end
end
end
end
describe Scorecard do
let(:perfect_game) { Scorecard.new('Kevin 10 10 10 10 10 10 10 10 10 10 10 10')}
it 'has a bowler name' do
expect(perfect_game.bowler).to eq('Kevin')
end
describe '#total_score' do
it 'returns the correct score' do
expect(perfect_game.total_score).to eq(300)
end
end
describe '#score_for' do
it 'return the correct score for the given frame' do
expect(perfect_game.score_for(1)).to eq(30)
end
end
describe '#generate_frames' do
it 'returns an array of frames' do
expect(perfect_game.generate_frames.first).to be_a(Frame)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment