52700.fb2
-> gameLoop $ move m game
askForMove :: IO Query
askForMove = showAsk >>
getLine >>= maybe askAgain return . parseQuery
where askAgain = wrongMove >> askForMove
parseQuery :: String -> Maybe Query
parseQuery = un
readInt :: String -> Maybe Int
readInt = un
Ответы пользователю (putStrLn)
greetings :: IO ()
greetings = un
showResults :: Game -> IO ()
showResults g = showGame g >> putStrLn ”Игра окончена.”
showGame :: Game -> IO ()
showGame = putStrLn . show
showAsk :: IO ()
showAsk = un
quit :: IO ()
quit = putStrLn ”До встречи.” >> return ()
По этим функциям видно, что нам немного осталось. Теперь вернёмся к запросам пользователя.
Формат запросов
Можно вывести с помощью deriving экземпляр класса Read для типа Query и читать их функцией read.
Но это плохая идея, потому что пользователь нашей программы может и не знать Haskell. Лучше введём
сокращённые имена для всех значений. Например такие:
208 | Глава 13: Поиграем
left
-- Play Left
right
-- Play Rigth
up
-- Play Up
down
-- Play Down
quit
-- Quit
new n
-- NewGame n
Можно обратить внимание на то, что все команды начинаются с разных букв. Воспользуемся этим и дадим
пользователю возможность набирать команды одной буквой. Это приводит на с к таким определениям для
функций разбора значения и напоминания ходов:
parseQuery :: String -> Maybe Query
parseQuery x = case x of
”up”
-> Just $ Play Up
”u”
-> Just $ Play Up
”down”
-> Just $ Play Down