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