Exit e-book
Show all chapters
18
Funcionalidad para mostrar por consola el estado del juego
18. 
Funcionalidad para mostrar por consola el estado del juego

Sign up to our Newsletter

Signing up to our newsletter allows you to read all our ebooks.

    Introducción a la Programación con Efectos Funcionales usando ZIO
    18

    Funcionalidad para mostrar por consola el estado del juego

    Lo siguiente que necesitamos hacer es implementar la funcionalidad para mostrar por consola el estado del juego:

    def renderState(state: State): URIO[Console, Unit] = {
    
      /*
         --------
         |      |
         |      0
         |     \|/
         |      |
         |     / \
         -
    
         f     n  c  t  o
         -  -  -  -  -  -  -
         Guesses: a, z, y, x
      */
      val hangman = ZIO(hangmanStages(state.failuresCount)).orDieWith(_ => new Error("Boom!"))
      val word =
        state.word.toList
          .map(c => if (state.guesses.map(_.char).contains(c)) s" $c " else "   ")
          .mkString
    
      val line    = List.fill(state.word.length)(" - ").mkString
      val guesses = s" Guesses: ${state.guesses.map(_.char).mkString(", ")}"
    
      hangman.flatMap { hangman =>
        putStrLn(
          s"""
           #$hangman
           #
           #$word
           #$line
           #
           #$guesses
           #
           #""".stripMargin('#')
        )
      }
    }
    

    No entraremos en mucho detalle de cómo esta función está implementada, más bien nos centraremos en una sola línea, que es quizás la más interesante:

    val hangman = ZIO(hangmanStages(state.failuresCount)).orDie
    

    Podemos ver que lo que hace esta línea es, primeramente, seleccionar cuál es la figura que se deberá mostrar para representar al ahorcado, la cual es diferente de acuerdo a la cantidad de fallas que haya tenido el jugador (el archivo com/example/package.scala contiene una variable hangmanStates que consiste en una lista con las seis posibles figuras). Por ejemplo:

    • hangmanStates(0) contiene el dibujo del ahorcado para failuresCount=0, es decir muestra solamente el dibujo de la horca sin el ahorcado
    • hangmanStates(1) contiene el dibujo del ahorcado para failuresCount=1, es decir muestra el dibujo de la horca y la cabeza del ahorcado.

    Ahora bien, la expresión hangmanStages(state.failuresCount)no es puramente funcional porque podría lanzar una excepción si es que state.failuresCount fuera mayor a 6. Entonces, como estamos trabajando con programación funcional no podemos permitir que nuestro código produzca efectos colaterales, como lanzar excepciones, es por ello que hemos encapsulado la anterior expresión dentro de ZIO, que en realidad es una llamada al método ZIO.apply, el cual permite construir un efecto funcional a partir de una expresión que produce efectos colaterales (también podemos usar el método equivalente ZIO.effect). Por cierto, el resultado de llamar a ZIO.apply es un efecto que puede fallar con un Throwable, pero de acuerdo al diseño de nuestra aplicación esperamos que en realidad nunca exista un fallo al intentar obtener el dibujo del ahorcado (puesto que state.failuresCount nunca debería ser mayor a 6). Por tanto, podemos descartar el caso erróneo llamando al método ZIO#orDie, el cual retorna un efecto que nunca falla (ya sabemos que si existiera alguna falla, sería en realidad un defecto y nuestra aplicación debería fallar inmediatamente). Por cierto, ZIO#orDie es muy similar a ZIO#orDieWith, pero sólo puede ser usado con efectos que fallan con un Throwable.

    PREVIOUS
    Chapter
    17
    NEXT
    Chapter
    19