module Hangman
where

import Control.Monad (when, unless)
-- import Control.Monad.Trans.State.Strict (StateT, put, get, modify)


-- type State = StateT (Input, Guess) IO

type Input =
  String

type Guess =
  String

hangman :: IO ()
hangman =
  do
    putStr "Enter a word: "
    word <- getLine
    play word ""
    hangman
    where
      play word guess =
        do c <- getChar
           let (progress, newGuess) =
                 game word guess c
           putStrLn $ " " ++ progress
           when (guessing progress) (play word newGuess)
             where
               guessing xs =
                 xs `contains` '-'


game :: String -> String -> Char -> (String, String)
game word guess c =
  (reveal, (c:guess))
  where
    reveal =
      [dash x | x <- word]

    dash x
      | (c:guess) `contains` x =
          x
      | otherwise =
          '-'


contains :: String -> Char -> Bool
contains xs c  =
  [] /= filter (==c) xs

module Hangman (hangman)
where

import Control.Monad (when)

hangman :: IO ()
hangman =
  do
    word <- getWord
    win <- play word "" 0
    when win hangman
    where
      getWord :: IO String
      getWord =
        do putStr "Enter a word: "
           getLine


play :: String -> String -> Int -> IO Bool
play word guess mistakeCount =
  do c <- getChar
     let (progress, newGuess, success) =
           game word guess c
         newMistakeCount =
           if success then mistakeCount else mistakeCount + 1
     putStrLn $ " " ++ progress
     putStr (hangmanFigure !! newMistakeCount)
     if gameOver newMistakeCount then return False
     else if guessing progress then play word newGuess newMistakeCount
     else return True
       where
         gameOver n =
           n == length hangmanFigure - 1

         guessing =
           elem '-'


--   O
--  /|\
--   |
--  / \
hangmanFigure :: [String]
hangmanFigure =
  [ ""
  , " O\n"
  , " O\n/\n"
  , " O\n/|\n"
  , " O\n/|\\\n"
  , " O\n/|\\\n |\n"
  , " O\n/|\\\n |\n/\n"
  , " O\n/|\\\n |\n/ \\\n"
  ]


game :: String -> String -> Char -> (String, String, Bool)
game word guess c =
  (reveal, newGuess, elem c word)
  where
    newGuess =
      c:guess

    reveal =
      [dash x | x <- word]

    dash x
      | elem x newGuess =
          x
      | otherwise =
          '-'

Add hangman ASCII figure + refactorings
Add hangman ASCII figure + refactorings
