Skip to content

Instantly share code, notes, and snippets.

@shishkin
Created October 20, 2013 15:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shishkin/7071262 to your computer and use it in GitHub Desktop.
Save shishkin/7071262 to your computer and use it in GitHub Desktop.
Kata Tennis in Scala using pattern matching on sealed types.
package kataTennis
sealed trait Player
case object Player1 extends Player
case object Player2 extends Player
sealed trait Score {
def inc: Score = this match {
case Score0 => Score15
case Score15 => Score30
case Score30 => Score40
case Score40 => throw new Error("Overscored")
}
}
case object Score0 extends Score
case object Score15 extends Score
case object Score30 extends Score
case object Score40 extends Score
sealed trait Game {
def score(player: Player): Game
}
sealed case class Points(player1: Score, player2: Score) extends Game {
def score(scorer: Player) = (scorer, player1, player2) match {
case (Player1, Score30, Score40) => Deuce
case (Player2, Score40, Score30) => Deuce
case (Player1, Score40, _) => Won(scorer)
case (Player2, _, Score40) => Won(scorer)
case (Player1, _, _) => Points(player1.inc, player2)
case (Player2, _, _) => Points(player1, player2.inc)
}
}
case object Deuce extends Game {
def score(scorer: Player) = Advantage(scorer)
}
sealed case class Advantage(leader: Player) extends Game {
def score(scorer: Player) =
if (scorer == leader) Won(scorer)
else Deuce
}
sealed case class Won(winner: Player) extends Game {
def score(scorer: Player) = throw new Error("Game over")
}
object Game {
val New = Points(Score0, Score0)
def test {
assert(Points(Score40, Score0).score(Player1) == Won(Player1),
"40:0 wins")
assert(Deuce.score(Player1).score(Player2) == Deuce,
"deuce -> deuce")
assert(Deuce.score(Player2).score(Player2) == Won(Player2),
"deuce -> win")
println("OK")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment