Skip to content

Instantly share code, notes, and snippets.

@haru01
Created September 16, 2011 22:11
Show Gist options
  • Save haru01/1223283 to your computer and use it in GitHub Desktop.
Save haru01/1223283 to your computer and use it in GitHub Desktop.
# encoding: utf-8
describe "ボウリングのスコア" do
subject { BowlingGame.new }
[
["すべてガーターの計算ができること", [0] * 21, 0],
["すべて1ピンの計算ができること", ([1, 1] * 10).concat([0]), 20],
["始めスペアの場合の計算ができること", [7, 3, 9, 0].concat([0] * 17), 28],
["最後スペアの場合の計算ができること", ([0] * 18).concat([7, 3, 9]), 19],
["先頭ストライクの計算ができること", [10, 0, 4, 3].concat([0] * 17), 24],
["最後ストライクの計算ができること", ([0, 0] * 9).concat([10,5,5]), 20],
["最後-1ストライクの計算ができること", ([0, 0] * 8).concat([10,0,10,5,0]), 40],
["パーフェクトゲームの計算ができること", ([10, 0] * 9).concat([10, 10, 10]), 300],
["サンプルの計算が出来ること", [5,4,0,0,10,0,9,1,6,3,7,0,6,2,10,0,10,0,1,9,5], 125],
].each do |desc, rolls, expected_score|
it "#{desc}: rolls:#{rolls}, score:#{expected_score}" do
rolls.size.should == 21
subject.score(rolls).should == expected_score
end
end
end
class BowlingGame
def score(rolls)
(1..10).map { |frame_index|
sub_score(rolls, frame_index)
}.reduce(:+)
end
def sub_score(rolls, frame_index)
rolls[range(rolls, frame_index)].reduce(:+)
end
private
def range(rolls, frame_index)
first_index = (frame_index - 1) * 2
return (first_index..first_index + 4) if strike?(rolls[first_index]) and strike?(rolls[first_index + 2]) and not pre_last_frame?(frame_index)
return (first_index..first_index + 3) if strike?(rolls[first_index])
return (first_index..first_index + 2) if spaire?(rolls[first_index], rolls[first_index + 1])
(first_index..first_index + 1)
end
def spaire?(first, second)
first + second == 10 and !strike?(first)
end
def strike?(first)
first == 10
end
def pre_last_frame?(frame_index)
frame_index == 9
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment