Skip to content

Instantly share code, notes, and snippets.

@francbreno
Last active September 5, 2019 12:22
Show Gist options
  • Save francbreno/cde5c371073e474fa4b9c04f7ebf4fcb to your computer and use it in GitHub Desktop.
Save francbreno/cde5c371073e474fa4b9c04f7ebf4fcb to your computer and use it in GitHub Desktop.
package playground
import scala.annotation.tailrec
import scala.io.StdIn
import scala.util.Random
trait Action {
def actionType(): String
}
case class GuessAction(wasRight: Boolean, result: String) extends Action {
override def actionType(): String = "GUESS"
}
case class GameState(tries: Int, wins: Int, lastResult: String, continue: Boolean = true)
object GameState {
def update(state: GameState, action: Action): GameState = action match {
case GuessAction(true, result) => state.copy(tries = state.tries + 1, wins = state.wins + 1, lastResult = result)
case GuessAction(false, result) => state.copy(tries = state.tries + 1, lastResult = result)
case _ => state
}
}
object PlayerInteraction {
def inputOption(): String = StdIn.readLine.toUpperCase
}
object GameInterface {
def showPrompt() = print("\n(h)eads, (t)ails or (q)quit? ")
def showState(state: GameState) = println(s"tries: ${state.tries}, wins: ${state.wins}")
def showAttemptResult(wasRight: Boolean) =
if(wasRight) println("Yes! You guessed it!")
else println("Sorry! You're wrong")
def showGameOver(state: GameState) = {
println("================")
println("Game Over")
println("================")
}
}
object Game extends App {
def start = gameLoop(GameState(0, 0, "", true), Random)
@tailrec
def gameLoop(state: GameState, random: Random): Unit = {
// Shows the prompt
GameInterface.showPrompt()
// get user input (heads, tails or quit)
val userOption = PlayerInteraction.inputOption()
// Check user input
userOption match {
case "H" | "T" => {
val side = flipCoin(random.nextInt(2))
val rightGuess = isGuessRight(userOption, side)
val action =
if(rightGuess) new GuessAction(true, side)
else new GuessAction(false, side)
val nextState = GameState.update(state, action)
guessResult(nextState, rightGuess)
gameLoop(nextState, random)
}
case "Q" => endGame(state)
case _ => gameLoop(state, random)
}
}
def isGuessRight(playerGuess: String, side: String) =
playerGuess == side
def guessResult(state: GameState, wasRight: Boolean) = {
GameInterface.showAttemptResult(wasRight)
GameInterface.showState(state)
}
def endGame(state: GameState) = {
GameInterface.showGameOver(state)
GameInterface.showState(state)
}
def flipCoin(value: Int): String = value match {
case 0 => "H"
case 1 => "T"
case _ => "?"
}
Game.start
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment