Skip to content

Instantly share code, notes, and snippets.

@nuboat
Created October 1, 2018 15:28
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 nuboat/efeeab93d17e9ed33dcd1cf477295657 to your computer and use it in GitHub Desktop.
Save nuboat/efeeab93d17e9ed33dcd1cf477295657 to your computer and use it in GitHub Desktop.
Hangman 2 with Scala Akka
package in.norbor.bigbears.hangman2
import akka.actor.{ActorRef, ActorSystem, Props}
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.io.StdIn
import scala.language.postfixOps
import scala.util.{Failure, Success}
/**
* @author Peerapat A on Oct 1, 2018
*/
object Main extends App {
private implicit val timeout: Timeout = Timeout(13 seconds)
private val streamer = start("bigbears")
while (true)
(streamer ? StdIn.readChar())
.onComplete {
case Success(s: State) =>
println(s)
if (s.status != Status.InGame)
System.exit(0)
case Failure(e) =>
e.printStackTrace()
}
def start(word: String): ActorRef = system.actorOf(Props(classOf[Streamer]), word)
private lazy val system: ActorSystem = ActorSystem("Norbor")
}
package in.norbor.bigbears.hangman2
import in.norbor.bigbears.hangman2.Status.Status
/**
* @author Peerapat A on Oct 1, 2018
*/
case class State(selected: List[Char]
, status: Status
, lifeLeft: Int) {
def knownSecret: String = selected.mkString("")
def correct(update: List[Char]): State = if (update.contains('_'))
this.copy(selected = update)
else
this.copy(status = Status.Win, selected = update)
}
object State {
def apply(word: String): State = State(
status = Status.InGame
, selected = word.map(_ => '_').toList
, lifeLeft = 7)
}
package in.norbor.bigbears.hangman2
/**
* @author Peerapat A on Oct 1, 2018
*/
object Status extends Enumeration {
type Status = Value
val InGame: Value = Value
val Win: Value = Value
val Lose: Value = Value
}
package in.norbor.bigbears.hangman2
import akka.actor.Actor
/**
* @author Peerapat A on Oct 1, 2018
*/
class Streamer extends Actor {
private val word = self.path.name
private var state = State(word)
private val secret = self.path.name.toCharArray
def receive: PartialFunction[Any, Unit] = {
case c: Char =>
state = if (!secret.contains(c))
if (state.lifeLeft > 0)
state.copy(lifeLeft = state.lifeLeft - 1)
else
state.copy(status = Status.Lose)
else
state.correct(secret.zipWithIndex.filter(_._1 == c).map(_._2).foldLeft(state.selected)((x, y) => x.patch(y, Seq(c), 1)))
sender() ! state
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment