Advertisement
Guest User

Haskell Hangman

a guest
Aug 14th, 2016
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. {-# LANGUAGE TupleSections #-}
  2. import System.IO(hFlush, stdout)
  3. import System.Random(randomRIO)
  4. import Control.Arrow(second)
  5. import Data.List(intersperse, intersect, nub)
  6.  
  7. dictFile = "dict.txt" -- first line is # of words, following lines are words
  8.  
  9. type Game = (String,[Char]) -- (word,guess)
  10. data GameStatus
  11.   = Win
  12.   | Lose
  13.   | Playing
  14.  
  15. instance Show GameStatus where
  16.   show Win = "YOU WIN"
  17.   show Lose = "YOU LOSE"
  18.   show Playing = ""
  19.  
  20. addGuess :: Char -> Game -> Game
  21. addGuess c = second (nub . (++ [c]))
  22.  
  23. goodGuesses :: Game -> Int
  24. goodGuesses game@(word,guess) = length $ nub $ intersect word guess
  25.  
  26. badGuesses :: Game -> Int
  27. badGuesses game@(word,guess) = length guess - goodGuesses game
  28.  
  29. revealed :: Game -> [Char]
  30. revealed game@(word,guess) = reveal <$> word
  31.   where
  32.     reveal c | c `elem` guess = c
  33.     reveal _ = '_'
  34.  
  35. statusOf :: Game -> GameStatus
  36. statusOf game@(word,guess) =
  37.   if badGuesses game >= 5 then
  38.     Lose
  39.   else if intersect word guess == word then
  40.     Win
  41.   else
  42.     Playing
  43.  
  44. asciiMan :: [[String]]
  45. asciiMan =
  46.   [ ["     "
  47.     ,"     "
  48.     ,"     "
  49.     ,"     "]
  50.   , ["  O  "
  51.     ,"     "
  52.     ,"     "
  53.     ,"     "]
  54.   , ["  O  "
  55.     ,"  |  "
  56.     ,"  |  "
  57.     ,"     "]
  58.   , ["  O  "
  59.     ,"--|--"
  60.     ,"  |  "
  61.     ,"     "]
  62.   , ["  O  "
  63.     ,"--|--"
  64.     ,"  |  "
  65.     ," /   "]
  66.   , ["  O  "
  67.     ,"--|--"
  68.     ,"  |  "
  69.     ," / \\ "] ]
  70.  
  71. asciiHangar :: [String] -> [String]
  72. asciiHangar man =
  73.   ["    /-----| "] ++
  74.   (pad <$> man) ++
  75.   ["          | "
  76.   ,"----------+-"]
  77.   where
  78.     pad s = "  " ++ s ++ "   | "
  79.  
  80. asciiGame :: Game -> [String]
  81. asciiGame game@(word,guess) = zipWith (++) hangar texts
  82.   where
  83.     bad = badGuesses game
  84.     hangar = asciiHangar $ asciiMan !! (min 5 bad)
  85.     texts = [ "word: " ++ intersperse ' ' (revealed game)
  86.             , ""
  87.             , "guesses: " ++ show (length guess)
  88.             , " " ++ intersperse ' ' guess
  89.             , ""
  90.             , show (statusOf game)
  91.             , "" ]
  92.  
  93. hangman :: Game -> IO ()
  94. hangman game =
  95.   mapM_ putStrLn (asciiGame game) >>
  96.   case statusOf game of
  97.     Win ->
  98.       return ()
  99.  
  100.     Lose -> do
  101.       putStr $ "\nthe word was: " ++ fst game
  102.       putStr "\nplay again? (y/n) "
  103.       hFlush stdout
  104.       p <- getLine
  105.       if p == "y" then
  106.         main
  107.       else
  108.         return ()
  109.  
  110.     Playing -> do
  111.       putStr "\nguess a letter: "
  112.       hFlush stdout
  113.       (c:_) <- getLine
  114.       hangman $! (addGuess c game)
  115.  
  116. randomWord :: IO String
  117. randomWord = do
  118.   (x:xs) <- lines <$> readFile dictFile
  119.   let n = read x
  120.   k <- randomRIO (0,n-1)
  121.   return $! xs !! k
  122.  
  123. main :: IO ()
  124. main = randomWord >>= hangman . (,[])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement