Rád s nadsázkou říkávám, že Kotlin je tak produktivní, že občas už ani sám nevím, co bych v něm dál napsal, neboť jak by se na Ostravsku řeklo “bo všecko je už zrobene” 🙂 . A tak jsem si při příležitosti víkendové nudy řekl, že si jen tak napíšu jednoduchou konzolovou hru Hangman (Šibenice/Oběšenec). Pokud byste dokázali kód refaktorovat do ještě lepší podoby, podělte se v komentářích 🙂 , nicméně tady to je a přeji příjemnou zábavu:

package com.svetylkovo.games.hangman

object Hangman {

    private var remainingWrongAttempts = 5
    private var word = ""

    private val guessedLetters = mutableSetOf<Char>()
    private val wrongGuesses = mutableSetOf<Char>()

    @JvmStatic
    fun main(args: Array<String>) {

        println("Let's play Hangman!")
        println("Type a word to be guessed:")

        word = readLine()?.nullIfBlank() ?: "HANGMAN"

        clearScreen()

        println("\nStart guessing!\n")

        while (remainingWrongAttempts > 0) {
            val hiddenWord = getHiddenWord()

            if ('_' !in hiddenWord) {
                println("You did it!")
                return
            }

            println("Word: ${hiddenWord.replace(Regex("."), "$0 ")}")
            printWrongGuesses()
            println("Remaining wrong attempts: $remainingWrongAttempts")
            println("Guess a letter:")

            val letter = readLine()?.nullIfBlank()
                ?.toUpperCase()
                ?.first()

            if (letter != null) {
                guessedLetters += letter

                if (letter in word) {
                    println("\nCorrect!\n")
                } else {
                    println("\nWrong!\n")
                    wrongGuesses += letter
                    remainingWrongAttempts--
                }
            }
        }

        println("You've been hanged! :-(")
    }

    private fun printWrongGuesses() {
        if (wrongGuesses.isNotEmpty()) {
            println("Wrong guesses: ${wrongGuesses.joinToString(", ")}")
        }
    }

    private fun getHiddenWord() = word.map { letter ->
        if (letter in guessedLetters) letter else '_'
    }.joinToString("")

    private fun clearScreen() = repeat(25) { println() }

    private fun String.nullIfBlank() = if (isBlank()) null else this
}