Skip to content

Instantly share code, notes, and snippets.

@philipschwarz
Created July 12, 2011 21:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save philipschwarz/1079052 to your computer and use it in GitHub Desktop.
Save philipschwarz/1079052 to your computer and use it in GitHub Desktop.
code kata - bowling - groovy - 2011.07.12
package bowling
class Frame
{
public Frame(){}
public Frame(Frame nextFrame)
{
this.nextFrame = nextFrame
}
public nextFrame(){ nextFrame }
public add(roll) { rolls << roll }
public score()
{
if(isStrike())
{
roll(1) + sumOfNextTwoRolls()
}
else if(isSpare())
{
roll(1) + roll(2) + nextRoll()
}
else
{
roll(1) + roll(2)
}
}
public isIncomplete() { !isComplete() }
private rolls = []
private nextFrame
private sumOfNextTwoRolls()
{
if(isLast())
{
roll(2) + roll(3)
}
else
{
if(nextFrame.isStrike() && !nextFrame.isLast())
{
nextFrame.roll(1) + nextFrame.nextFrame.roll(1)
}
else
{
nextFrame.roll(1) + nextFrame.roll(2)
}
}
}
private nextRoll()
{
if(isLast())
{
return roll(3)
}
else
{
return nextFrame.roll(1)
}
}
private isComplete()
{
if(isLast())
{
(hasTwoRolls() && !isStrike() && !isSpare()) || hasThreeRolls()
}
else
{
(hasOneRoll() && isStrike()) || hasTwoRolls()
}
}
private roll(n){ rolls[n-1] }
private isStrike(){ roll(1) == 10 }
private isSpare(){ (roll(1) + roll(2)) == 10 }
private isLast(){ nextFrame == null }
private hasOneRoll(){ rolls.size == 1 }
private hasTwoRolls(){ rolls.size == 2 }
private hasThreeRolls(){ rolls.size == 3 }
}
package bowling
import java.util.Iterator;
class FrameSequence
{
public FrameSequence(n)
{
def firstFrameInSequence = createSequenceOfLength(n)
frames = getAllFramesInSequence(firstFrameInSequence)
}
public populateWith(rolls){ populateWith(rolls.iterator()) }
public score() { frames.sum{ it.score() } }
private getAllFramesInSequence(firstFrame)
{
def frames = [firstFrame]
def frame = firstFrame
while(!frame.isLast())
{
frame = frame.nextFrame()
frames << frame
}
return frames
}
private populateWith(Iterator rolls)
{
frames.each
{
populate(it, with(rolls))
}
}
private populate(frame, rolls)
{
while (frame.isIncomplete())
{
frame.add(rolls.next())
}
}
private frames
private static createSequenceOfLength(n){ n==1 ? new Frame() : new Frame(createSequenceOfLength(n-1)) }
private with(rolls){rolls}
private ofLength(n){n}
}
package bowling
class Game
{
public Game(rolls)
{
frameSequence = new FrameSequence(NUMBER_OF_ROLLS_IN_A_GAME)
frameSequence.populateWith(rolls)
}
public score(){ frameSequence.score() }
private frameSequence
private static final NUMBER_OF_ROLLS_IN_A_GAME = 10
}
package bowling
class GameTest extends GroovyTestCase
{
public void test_all_ones()
{
assertEquals( 20, new Game([1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1 ]).score())
}
public void test_all_gutters()
{
assertEquals(0, new Game([0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ]).score())
}
public void test_strike_in_9th_frame()
{
assertEquals(30, new Game([1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 10, 1,1 ]).score() )
}
public void test_strike_in_last_frame()
{
assertEquals(30, new Game([1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 10,1,1 ]).score())
}
public void test_spare_in_9th_frame()
{
assertEquals(29, new Game([1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 5,5, 1,1 ]).score())
}
public void test_spare_in_last_frame()
{
assertEquals(29, new Game([1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 5,5,1 ]).score())
}
public void test_spare_in_3rd_frame_and_strike_in_6th_frame()
{
assertEquals(39, new Game([1,1, 1,1, 5,5, 1,1, 1,1, 10, 1,1, 1,1, 1,1, 1,1 ]).score())
}
public void test_all_spares()
{
assertEquals(150, new Game([5,5, 5,5, 5,5, 5,5, 5,5, 5,5, 5,5, 5,5, 5,5, 5,5,5 ]).score())
}
public void test_all_strikes()
{
assertEquals(300, new Game([10, 10, 10, 10, 10, 10, 10, 10, 10, 10,10,10 ]).score())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment