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

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

( Game. hs, interpreted )

[2 of 2] Compiling Loop

( Loop. hs, interpreted )

Ok, modules loaded: Game, Loop.

*Loop>

Модуль загрузился. Он потянул за собой модуль Game, потому что мы воспользовались типом Move из

этого модуля. Программа прошла проверку типов, значит она осмысленна и мы можем двигаться дальше.

У нас три варианта дальнейшей детализации это функции greetings, setup и gameLoop. Мы пока пропу-

стим greetings там мы напишем какое-нибудь приветствие и сообщим игроку куда он попал и как ходить.

204 | Глава 13: Поиграем

В функции setup нам нужно начать первую игру. Для начала игры нам нужно узнать её сложность, на

сколько ходов перемешивать позицию. Это значит, что нам нужно спросить у игрока целое число. Мы спро-

сим число функцией getLine, а затем попробуем его распознать. Если пользователь ввёл не число, то мы

попросим его повторить ввод. Функция readInt :: String -> Maybe Int распознаёт число. Она возвращает

целое число завёрнутое в Maybe, потому что строка может оказаться не числом. Затем это число мы исполь-

зуем в функции shuffle (перемешать), которая будет возвращать позицию, которая перемешана с заданной

глубиной.

-- в модуль Loop

setup :: IO Game

setup = putStrLn ”Начнём новую игру?” >>

putStrLn ”Укажите сложность (положительное целое число): ” >>

getLine >>= maybe setup shuffle . readInt

readInt :: String -> Maybe Int

readInt = un

-- в модуль Game:

shuffle :: Int -> IO Game

shuffle = un

Функция shuffle возвращает состояние игры Game, которое завёрнуто в IO. Оно завёрнуто в IO, потому

что перемешивать позицию мы будем случайным образом, это значит, что мы воспользуемся функциями из

модуля Random. Мы хотим чтобы каждая новая игра начиналась с новой позиции, поэтому скорее всего где-то

в недрах функции shuffle мы воспользуемся newStdGen, которая и потянет за собой тип IO.

Игра перемешивается согласно правилам, поэтому функцию shuffle мы поселим в модуле Game. А функ-

ция readInt это скорее элемент взаимодействия с пользователем, ведь в ней мы распознаём число в строчном

ответе, она останется в модуле Loop.

Проверим работает ли наша программа:

*Loop> :r

[1 of 2] Compiling Game

( Game. hs, interpreted )

[2 of 2] Compiling Loop

( Loop. hs, interpreted )

Ok, modules loaded: Game, Loop.

*Loop>

Работает! Можно спускаться по дереву выражения ниже. Сейчас нам предстоит написать одну из самых

сложных функций, это функция gameLoop.

13.2 Пятнашки

Цикл игры

Функция цикла игры принимает текущую позицию. При этом у нас два варианта. Возможно игра пришла

в конечное положение (isGameOver) и мы можем сообщить игроку о том, что он победил (showResults), если

это не так, то мы покажем текущее положение (showGame), спросим ход (askForMove) и среагируем на ход

(reactOnMove).