Skip to content

Instantly share code, notes, and snippets.

@jocke-l
Last active December 17, 2015 12:09
Show Gist options
  • Save jocke-l/5607845 to your computer and use it in GitHub Desktop.
Save jocke-l/5607845 to your computer and use it in GitHub Desktop.
Hangman in Haskell
module Main where
import System.Random
import Data.List (intersect)
import Prelude hiding (words)
import Text.Printf
obscure word letters = map hide word
where hide c
| c `elem` (' ' : letters) = c
| otherwise = '_'
guess word letters trials
| errors >= 11 = printf "omg, hes neck is broken! %s!\n" word
| '_' `elem` obscured = do printf "%d (%s) %s: " errors error_chars obscured
input <- getLine
guess word (letters ++ input) (trials + length input)
| otherwise = printf "woo! you did it! %s!\n" word
where obscured = obscure word letters
errors = trials - length (letters `intersect` obscured)
error_chars = filter (`notElem` obscured) letters
main = do
printf "hangman\n\n"
r <- newStdGen
words <- fmap lines (readFile "/usr/share/dict/british-english")
let (num, newr) = randomR (0, length words - 1) r
guess (words !! num) [] 0
{-
Runtime example:
0 () ____________: arstoiendh
3 (rdh) e__itation_s: m
4 (rdhm) e__itation_s: k
5 (rdhmk) e__itation_s: t
5 (rdhmk) e__itation_s: c
5 (rdhmk) e_citation_s: x
5 (rdhmk) excitation_s: '
woo! you did it! excitation's!
---
0 () _______: arstoiendh
5 (oindh) _a_ster: m
6 (oindhm) _a_ster: r
6 (oindhm) _a_ster: f
7 (oindhmf) _a_ster: l
8 (oindhmfl) _a_ster: g
9 (oindhmflg) _a_ster: w
10 (oindhmflgw) _a_ster: q
omg, hes neck is broken! Napster!
-}
@kqr
Copy link

kqr commented May 20, 2013

because you're in the IO monad anyway, the main function could be written as just

main = do
   printf "hangman\n\n"
   words <- fmap lines (readFile "/usr/share/dict/british-english")
   num <- randomRIO (0, length words - 1)
   guess (words !! num) [] 0

randomRIO works pretty much like randomR, only in the IO monad and it uses a global generator so it doesn't need an explicit one.

@kqr
Copy link

kqr commented May 20, 2013

I still think you should disallow words with apostrophes. And you should lowercase all words before using them. And you shouldn't get an error if you guess the same wrong character twice. :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment