52700.fb2
Quit
->
NewGame n
->
Play
m
->
Рассмотрим каждый из случаев. В первом случае пользователь говорит, что ему надоело и он уже наиг-
рался. Чтож попрощаемся и вернём значение единичного типа.
206 | Глава 13: Поиграем
...
Quit
-> quit
...
quit :: IO ()
quit = putStrLn ”До встречи.” >> return ()
В следующем варианте пользователь хочет начать всё заново. Так начнём!
NewGame n
-> gameLoop =<< shuffle n
Мы вызвали функцию перемешивания shuffle с заданным уровнем сложности. И рекурсивно вызвали
цикл игры с новой позицией. Всё началось по новой. В третьей альтернативе пользователь делает ход, на это
мы должны обновить позицию запустить цикл игры с новым значением:
-- в модуль Loop
Play
m
-> gameLoop $ move m game
-- в модуль Game
move :: Move -> Game -> Game
move = un
Функция move обновляет согласно правилам текущую позицию. Соберём все определения вместе:
reactOnMove :: Game -> Query -> IO ()
reactOnMove game query = case query of
Quit
-> quit
NewGame n
-> gameLoop =<< shuffle n
Play
m
-> gameLoop $ move m game
Слушаем игрока
Теперь всё же вернёмся к функции askForMove, научимся слушать пользователя. Сначала мы скажем
какую-нибудь вводную фразу, предложение ходить (showAsk) затем запросим строку стандартной функцией
getLine, потом нам нужно будет распознать (parseQuery) в строке значение типа Query. Если распознать его
нам не удастся, мы напомним пользователю как с нами общаться (remindMoves) и попросим сходить вновь:
askForMove :: IO Query
askForMove = showAsk >>
getLine >>= maybe askAgain return . parseQuery
where askAgain = wrongMove >> askForMove
parseQuery :: String -> Maybe Query