Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import scalaz._
- import Scalaz._
- import scalaz.Free._
- import game._
- implicit def dGameFunctor = new Functor[DGame] {
- def map[A, B](game: DGame[A])(f: A => B): DGame[B] = game match {
- case DContinue(next) => DContinue(f(next))
- case DInputRequired(next) => DInputRequired(next andThen f)
- case gameOver @ DGameOver(_) => gameOver
- }
- }
- def interpretGame(inputs: Seq[DInput], game: Free[DGame, DGameState]): DGameState = game.resume.fold({
- case DContinue(next) => interpretGame(inputs, next)
- case DInputRequired(next) => interpretGame(inputs.tail, next(inputs.head))
- case DGameOver(gameState) => gameState
- }, identity)
- def continue[Next](next: Next) = liftF(DContinue(next): DGame[Next])
- def getInput = liftF(DInputRequired(identity): DGame[DInput])
- def gameOver[Next](gameState: DGameState) = liftF(DGameOver(gameState): DGame[Next])
- def gameState(x: Int) = continue(DGameState(x))
- def applyInput(game: Free[DGame, DGameState]) = for {
- gameState <- game
- num = gameState.num
- input <- getInput
- result <- input match {
- case Inc => continue(DGameState(num+1))
- case Dec => continue(DGameState(num-1))
- case Add(x) => continue(DGameState(num+x))
- case Set(x) => continue(DGameState(x))
- case EndGame => gameOver[DGameState](gameState)
- }
- } yield result
- def gameWithInputs(initial: DGameState, numInputs: Int): Free[DGame, DGameState] =
- if(numInputs == 0) continue(initial)
- else for {
- nextState <- applyInput(continue(initial))
- result <- gameWithInputs(nextState, numInputs - 1)
- } yield result
- interpretGame(Nil, gameState(5)) // DGameState(5)
- interpretGame(Set(5) :: Inc :: Nil, applyInput(applyInput(gameState(0)))) // DGameState(6)
- interpretGame(Set(5) :: Inc :: Inc :: Nil, gameWithInputs(DGameState(0), 3)) // DGameState(7)
- interpretGame(Set(5) :: EndGame :: Inc :: Nil, gameWithInputs(DGameState(0), 3)) // DGameState(5)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement