Tests first:
require './score' require 'test/unit' class TestScore < Test::Unit::TestCase def test_score_uninteresting_game # 7 7 7 7 7 = 35 # 6 6 6 6 6 = 30 balls = "51|52|51|52|51|52|51|52|51|52" assert_equal 65, score(balls) end def test_score_all_frames_5_spare # 15 15 15 15 15 = 75 # 15 15 15 15 15 = 75 balls = "5/|5/|5/|5/|5/|5/|5/|5/|5/|5/|5" assert_equal 150, score(balls) end def test_perfect_score # 30 30 30 30 30 = 150 # 30 30 30 30 30 = 150 balls = "X|X|X|X|X|X|X|X|X|X|XX" assert_equal 300, score(balls) end def test_10_strikes_then_33 # 30 30 30 30 16 = 136 # 30 30 30 30 23 = 143 balls = "X|X|X|X|X|X|X|X|X|X|33" assert_equal 279, score(balls) end def test_game_with_spare_in_middle_of_strikes # 20 30 30 30 30 = 140 # 25 20 30 30 30 = 135 balls = "X|X|5/|X|X|X|X|X|X|X|XX" assert_equal 275, score(balls) end def test_game_with_strike_in_middle_of_spares # 15 20 15 13 20 = 83 # 13 11 20 14 12 = 70 balls = "2/|3/|5/|1/|X|3/|5/|4/|3/|2/|X" assert_equal 153, score(balls) end def test_game_with_zero_balls # 8 7 7 7 7 = 36 # 6 5 6 6 6 = 29 balls = "51|62|50|52|51|52|51|52|51|52" assert_equal 65, score(balls) end def test_game_with_dash_as_zero_balls # 8 7 7 7 8 = 37 # 6 5 6 6 6 = 29 balls = "51|62|5-|52|51|52|51|52|51|62" assert_equal 66, score(balls) end endCode second:
def score(balls) frames = (balls).split("|") while frames.length != 12 frames << "0" end frames.each_cons(3).collect{ |frame| frame_score(frame) }.inject(:+) end def frame_score(frames) if strike? frames[0] 10 + strike_bonus(frames[1..2]) elsif spare? frames[0] 10 + ball_score(frames[1][0]) else frames[0].chars.collect{ |ball| ball_score(ball) }.inject(:+) end end def strike_bonus(frames) if frames[0] == "XX" 20 elsif strike? frames[0] 10 + ball_score(frames[1][0]) elsif spare? frames[0] 10 else ball_score(frames[0][0]) + ball_score(frames[0][1]) end end def ball_score(ball) if strike? ball 10 else ball.to_i end end def strike?(frame) frame == "X" end def spare?(frame) frame[-1] == "/" endIt took me a while to realize that each_slice should have been each_cons. You can replay my entire progression (warts and all) on Cyber-Dojo (naturally).
No comments:
Post a Comment