Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # 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
Add Comment
Please, Sign In to add comment