Skip to content

Instantly share code, notes, and snippets.

@tyrcho
Created February 3, 2016 12:39
Show Gist options
  • Save tyrcho/01adb5e9b88d7d17e978 to your computer and use it in GitHub Desktop.
Save tyrcho/01adb5e9b88d7d17e978 to your computer and use it in GitHub Desktop.
Bowling Game Kata - Scala implementation http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata
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)
}
}
}
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