52700.fb2 Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 229

Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 229

reactOnMove game query = case query of

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