[Haskell-beginners] Keyboard input

legajid legajid at free.fr
Sat Dec 5 17:20:22 EST 2009


Hello,
in order to get familiar with keyboard data entry, i'm writing a program 
for the well-known Hangman game.
Each entry must change several lists (letters found and remaining letters).
I have three main difficulties with data entry :

First When i enter a letter (A) , i get a good response (displaying old 
word and letters, message "guess ok") and an unattended one that says 
"guess false", thus displaying the result from my entry.
I don't understand why the process seems to execute twice, the fisrt one 
being correct, the second not.

Second difficulty : the  "procedure"  for data entry is written twice 
("guess a letter ..." prompt). I think it would be a good idea to write 
it once as a "function" that would display the prompt then get a 
character from the keyboard.

Third difficulty : in both cases (guess ok or false), i have to ask for 
a new entry; to avoid writing this twice again, i write it before the 
recursive calls of process_guess. Writing a function would perhaps allow 
to call it directly as a parameter of process_guess ?

Being new to haskell,  recursive functions now seem clear to me but i 
feel that IOs make writing a program more difficult. And i've not yet 
tried data base access...

Please, say me if the way i wrote my program is a good or bad approach.

Below an example of a run :


Here's my program.
Could you help me.
Thanks,
Didier

solution="HANGMAN"
word="H-----N"
letters=['A'..'Z']

hangman = do
  -- enter a letter
  putStrLn "Guess a letter (9 to end):"
  guess <- getChar
  -- process
  process_guess guess letters word
 
process_guess pg pletters pword =do
  let pguess = toUpper pg
  putStrLn pword
  putStrLn pletters
  if pguess == '9'
    then do putStrLn "Done"
    else do
      if pguess `elem` pletters
        then do putStrLn "Guess OK \n"
        else do putStrLn "Guess false \n"
     
      -- Enter a new letter before going on, in both cases
      putStrLn "Guess a letter (9 to end):"
      guess <- getChar

      if pguess `elem` pletters
        -- guess ok -> remove guess from available letters then add 
guess to word
        then do process_guess guess (newletters pletters pguess) 
(newword pword pguess solution)
       
        -- guess false -> remove guess from available letters, leave 
word unchanged
        else do process_guess guess (newletters pletters pguess) pword
       

newletters l g =
  filter (/= g) l
 

newword [] _ _ = []
newword (w:ws) g (s:ss) =
  if w == '-'
    then
      if s == g
        then g : newword ws g ss
        else w : newword ws g ss
    else
      w : newword ws g ss


toUpper c
  | isLower c = toEnum (fromEnum c - fromEnum 'a' + fromEnum 'A')
  | otherwise = c

isLower c = c >= 'a' && c <= 'z'



More information about the Beginners mailing list