Created
December 14, 2010 14:17
-
-
Save enriquez/740479 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'test/unit' | |
class Frame | |
attr_reader :rolls | |
def initialize(first_roll) | |
@rolls = [first_roll] | |
end | |
def << pins | |
@rolls << pins | |
end | |
def score | |
@rolls.inject(0) { |total,roll| total + roll } | |
end | |
def score_with_bonus(remaining_frames) | |
s = score | |
unless remaining_frames.empty? | |
next_rolls = remaining_frames[0..1].map{|f| f.rolls }.flatten | |
s += next_rolls[0].to_i if self.closed? | |
s += next_rolls[1].to_i if self.strike? | |
end | |
s | |
end | |
def unclosed? | |
@rolls.size == 1 && !strike? | |
end | |
def closed? | |
score == 10 | |
end | |
def strike? | |
@rolls.first == 10 | |
end | |
end | |
class Game | |
def initialize | |
@frames = [] | |
end | |
def roll pins | |
if @frames.size == 10 || (!@frames.empty? && @frames.last.unclosed?) | |
@frames.last << pins | |
else | |
@frames << Frame.new(pins) | |
end | |
end | |
def score | |
s = 0 | |
@frames.each_with_index do |frame,i| | |
s += frame.score_with_bonus(@frames[(i+1)..-1]) | |
end | |
s | |
end | |
end | |
class GameTest < Test::Unit::TestCase | |
def setup | |
@g = Game.new | |
end | |
def test_gutter_game | |
rolls 20.gutters | |
# roll_many(20,0) | |
assert_equal 0, @g.score | |
end | |
def test_all_ones | |
rolls '1'*20 | |
assert_equal 20, @g.score | |
end | |
def test_one_spare | |
rolls '553' + 17.gutters | |
assert_equal 16, @g.score | |
end | |
def test_one_strike | |
rolls 'x34' + 16.gutters | |
assert_equal 24, @g.score | |
end | |
def test_almost_perfect | |
rolls 'x'*10+'00' | |
assert_equal 270, @g.score | |
end | |
def test_perfect | |
rolls 'x'*12 | |
assert_equal 300, @g.score | |
end | |
def test_crazy_normal_game | |
rolls 'x |5/|3-|4/|x |24|81|x |x |1/3' | |
assert_equal 141, @g.score | |
end | |
def test_rolls | |
assert_equal 'x5532', numerify_rolls('x|5/|32') | |
end | |
def rolls string | |
numerify_rolls(string).each_char do |c| | |
@g.roll c.to_i | |
end | |
end | |
def numerify_rolls string | |
string.gsub(/[|\s]/,'').gsub(/(\d)\//){"#{$1}#{10-$1.to_i}"} | |
end | |
end | |
class String | |
alias :normal_to_i :to_i | |
def to_i | |
self == 'x' ? 10 : normal_to_i | |
end | |
end | |
class Fixnum | |
def gutters | |
'0' * self | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment