52700.fb2
и читаем целое число, иначе возвращаем Nothing.
Последняя функция, это функция приветствия. Когда игрок входит в игру он сталкивается с её результа-
тами. Определим её так:
-- в модуль Loop
greetings :: IO ()
greetings = putStrLn ”Привет! Это игра пятнашки” >>
showGame initGame >>
remindMoves
-- в модуль Game
initGame :: Game
initGame = un
Сначала мы приветствуем игрока, затем показываем состояние (initGame), к которому ему нужно стре-
миться, и напоминаем как делаются ходы. На этом определении мы раскрыли все выражения в модуле Loop,
нам остался лишь модуль Game.
Правила игры
Определим модуль Game, но мы будем определять его не с чистого листа. Те функции, которые нам нуж-
ны уже определились в ходе описания диалога с пользователем. Нам нужно уметь составлять начальное
состояние initGame, уметь составлять перемешанное состояние игры shuffle, нам нужно уметь реагиро-
вать на ходы move, определять какая позиция является выигрышной isGameOver и уметь показывать фишки
в красивом виде. Приступим!
initGame
:: Game
shuffle
:: Int -> IO Game
isGameOver
:: Game -> Bool
move
:: Move -> Game -> Game
instance Show Game where
show = un
Таков наш план.
210 | Глава 13: Поиграем
Начальное состояние
Начнём с самой простой функции, составим начальное состояние:
initGame :: Game
initGame = Game (3, 3) $ listArray ((0, 0), (3, 3)) $ [0 .. 15]
Мы будем кодировать фишки цифрами от нуля до 14, а пустая клетка будет равна 15. Это просто согла-
шения о внутреннем представлении фишек, показывать мы их будем совсем по-другому.
С этим значением мы можем легко определить функцию определения конца игры. Нам нужно только
добавить deriving (Eq) к типу Game. Тогда функция isGameOver примет вид:
isGameOver :: Game -> Bool
isGameOver = ( == initGame)
Делаем ход
Напишем функцию:
move :: Move -> Game -> Game
Она обновляет позицию после хода. В пятнашках не во всех позициях доступны все ходы. Если пустышка
находится на краю, мы не можем вывести её за пределы доски. Это необходимо как-то учесть. Каждый ход
задаёт направление обмена фишками. Если у нас есть текущее положение пустышки и ход, то по ходу мы
можем узнать направление, а по направлению ту фишку, которая займёт место пустышки после хода. При