View difference between Paste ID: 7DCjukPT and a5dXGE46
SHOW: | | - or go back to the newest paste.
1
module Main
2
( main
3
) where
4
5
import           Data.Char
6
import           Data.Set (Set)
7
import qualified Data.Set as S
8
import           Control.Monad.Reader
9
import           Control.Monad.IO.Class
10
11
type Hangman a = ReaderT String IO a
12
13
getFilteredChar :: (Char -> Bool) -> IO Char
14
getFilteredChar p = do
15
    c <- getChar
16
    if p c
17
        then return c
18
        else getFilteredChar p
19
20
printSeparator :: IO ()
21-
hangman :: Set Char -> ReaderT String IO ()
21+
22
23
hangman :: Set Char -> Hangman ()
24
hangman g | S.size g < 8 = do
25
                (g', won) <- guess g
26
                printState g' >> (liftIO printSeparator)
27
                if won then printWonMessage else hangman g'
28-
guess :: Set Char -> ReaderT String IO (Set Char, Bool)
28+
29
30
guess :: Set Char -> Hangman (Set Char, Bool)
31
guess g = do
32
    w <- ask
33
    c <- liftIO $ getFilteredChar isAlpha
34
    let g' = S.insert c g
35
    return $ (g', guessed w g')
36
37
guessed :: String -> Set Char -> Bool
38-
printGameOver :: ReaderT String IO ()
38+
39
40
printGameOver :: Hangman ()
41
printGameOver = do
42
    w <- ask
43-
printWonMessage :: ReaderT String IO ()
43+
44
45
printWonMessage :: Hangman ()
46-
printState :: Set Char -> ReaderT String IO ()
46+
47
48
printState :: Set Char -> Hangman ()
49
printState g = do
50
    w <- ask
51
    liftIO $ do
52
        putStrLn $ map (\c -> if c `S.member` g then c else '_') w
53
        putStrLn $ "Guessed: " ++ S.toList g
54
55
main :: IO ()
56
main = liftIO $ runReaderT (hangman S.empty) "hello"