Created
February 3, 2016 12:39
-
-
Save tyrcho/01adb5e9b88d7d17e978 to your computer and use it in GitHub Desktop.
Bowling Game Kata - Scala implementation http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata
This file contains hidden or 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
class BowlingGame { | |
var moves = Vector.empty[Int] | |
def roll(i: Int) = { | |
moves = moves :+ i | |
} | |
def score: Int = score() | |
def score(i: Int = 0, acc: Int = 0, frames: Int = 0): Int = | |
if (i >= moves.size || frames == 10) acc else { | |
val first = moves(i) | |
if (first == 10) score(i + 1, acc + 10 + moves(i + 1) + moves(i + 2), frames + 1) | |
else { | |
val second = moves(i + 1) | |
if (first + second == 10) score(i + 2, acc + 10 + moves(i + 2), frames + 1) | |
else score(i + 2, acc + first + second, frames + 1) | |
} | |
} | |
} |
This file contains hidden or 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
import org.junit.Test | |
class BowlingTest { | |
@Test | |
def scoreShouldBeZero = | |
testAllBalls(0, 0) | |
@Test | |
def scoreShouldBe20 = | |
testAllBalls(1, 20) | |
@Test | |
def scoreAfterOneSpare = { | |
val game = new BowlingGame | |
rollSpare(game) | |
repeatRoll(18, 1, game) | |
assert(game.score == 29, game.score) | |
} | |
def repeatRoll(count: Int, ball: Int, game: BowlingGame) = | |
for (i <- 1 to count) game.roll(ball) | |
@Test | |
def scoreAfterOneSpareInSecondFrame = { | |
val game = new BowlingGame | |
repeatRoll(2, 0, game) | |
rollSpare(game) | |
repeatRoll(16, 1, game) | |
assert(game.score == 27, game.score) | |
} | |
@Test | |
def scoreAfterOneStrikeInSecondFrame = { | |
val game = new BowlingGame | |
repeatRoll(2, 0, game) | |
game.roll(10) | |
repeatRoll(16, 4, game) | |
assert(game.score == 10 + 8 + 8 + 14 * 4, game.score) | |
} | |
@Test | |
def scoreForRealGame = { | |
val game = new BowlingGame | |
for (i <- Seq(1, 4, 4, 5, 6, 4, 5, 5, 10, 0, 1, 7, 3, 6, 4, 10, 2, 8, 6)) game.roll(i) | |
assert(game.score == 133, game.score) | |
} | |
@Test | |
def scoreAfterAllStrike = { | |
val game = new BowlingGame | |
repeatRoll(12, 10, game) | |
assert(game.score == 300, game.score) | |
} | |
def rollSpare(game: BowlingGame) = { | |
game.roll(5) | |
game.roll(5) | |
} | |
def testAllBalls(ball: Int, expected: Int) = { | |
val game = new BowlingGame | |
for (i <- 1 to 20) game.roll(ball) | |
assert(game.score == expected, game.score) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment