Как написать игровой цикл в Haskell?

Я хочу закодировать игру в Haskell, где каждая итерация цикла вычисляет состояние мира. Я думал, что должен создать функцию:

gameLoop :: World -> World
-- ...

и <<21 > :

main = do
    gameLoop -- ...

Но проблема в том, что мне не хватает фундаментального понимания того, как обернуть функцию gameLoop, чтобы она возвращала значение параметра main.

Как можно создать игровой цикл в Haskell?

Ответы

Ответ 1

Вероятно, вам понадобится что-то вроде этого

import Control.Monad.Loops

main = iterateM_ 
       (\w -> displayWorld w >> return (gameLoop w))
       initWorld
-- iterateM_ ((>>) <$> displayWorld <*> return . gameLoop) initWorld

Или, если вы не хотите использовать весь пакет монад-петель (даже если он качается)

main = loop initWorld
  where loop w = displayWorld w >> loop (gameLoop w)

В принципе, вы просто рисуете мир, а затем снова переходите к следующему состоянию.

Скорее всего, вам нужно что-то подобное, хотя

 -- False when the user wants to exit the game
 keepGoing :: World -> Bool

 main = iterateUntilM_ keepGoing displayLoop initWorld
   where displayLoop w = displayWorld w >> return (gameLoop w)

Так как в противном случае вы не можете остановить:)

Ответ 2

Я думаю, что вы заявили, что это функция перехода состояния, а сам игровой цикл должен быть рекурсивной. Общая идея выглядит так:

initialState :: World
nextState :: World -> World
isFinalState :: World -> Bool

gameLoop world | isFinalState world = -- ...
               | otherwise = do
                     drawScene world
                     gameLoop (nextState world)

main = gameLoop initialState

В initialState исходный мир может быть построен с начальными параметрами и т.д. И в nextState вы можете обрабатывать входы проигрывателя (клавиатуры и т.д.), которые изменят состояние мира. isFinalState используется для определения того, следует ли выйти из игрового цикла.

Эта структура несколько похожа на ту, которая часто используется в Erlang, например. Запросить процесс Erlang для своего состояния?