Skip to content

Instantly share code, notes, and snippets.

@jsanders
Created April 19, 2014 20:33
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 jsanders/11096688 to your computer and use it in GitHub Desktop.
Save jsanders/11096688 to your computer and use it in GitHub Desktop.
A simple game from "Introduction to Functional Game Programming using Scala" talk at lambdaconf2014
class IO[A] private (run0: => A) {
def run = run0
def flatMap[B](f: A => IO[B]): IO[B] = {
IO(f(run).run)
}
def map[B](f: A => B): IO[B] = flatMap(a => IO(f(a)))
}
object IO {
def apply[A](a: => A): IO[A] = new IO(a)
}
def point[A](a: => A): IO[A] = IO(a)
def getLine: IO[String] = IO(readLine())
def putStrLn(v: String): IO[Unit] = IO(println(v))
def intro: IO[String] = {
for {
_ <- putStrLn("Welcome to Text Adventure RPG v1.0!")
_ <- putStrLn("Please enter the name of your character: ")
name <- getLine
_ <- putStrLn("Welcome, " + name + ", it's time for an adventure!")
} yield name
}
def gameLoop: IO[Unit] = {
for {
_ <- putStrLn("What would you like to do now: ")
input <- getLine
_ <- putStrLn("You want to " + input)
_ <-
if (input == "quit" || input == "exit")
putStrLn("Goodbye!")
else
gameLoop
} yield Unit
}
(for {
name <- intro
_ <- gameLoop
} yield name)//.run
case class State[S, A](run: S => (S, A)) {
def flatMap[B](f: A => State[S, B]): State[S, B] = State[S, B] { s =>
val (s2, a) = run(s)
f(a).run(s2)
}
def map[B](f: A => B): State[S, B] = flatMap(a => State.point(f(a)))
}
object State {
def point[S, A](a: => A): State[S, A] = State(s => (s, a))
}
case class Player(health: Int)
case class GameState(player: Player)
type Game[A] = State[GameState, A]
def hurtPlayer(hp: Int): Game[Int] = State { s =>
val newHealth = s.player.health - hp
val newState = s.copy(player = s.player.copy(health = newHealth))
(newState, newHealth)
}
val InitialState = GameState(Player(100))
val gameState = for {
_ <- hurtPlayer(10)
_ <- hurtPlayer(40)
h <- hurtPlayer(60)
} yield h
println(gameState.run(InitialState))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment