Haskell 生命游戏在启动时崩溃
Posted
技术标签:
【中文标题】Haskell 生命游戏在启动时崩溃【英文标题】:A Haskell Game of life crashes when launched 【发布时间】:2014-08-26 08:18:40 【问题描述】:我目前正在尝试在 Haskell 中开发一个小型的康威生命游戏。我编写了一个库,lifegame,它可以管理单元格并计算其世代 (见github.com/qleguennec/lifegame.git)。 Generations 是一个无限列表。 到目前为止,该库运行良好,但缺少文档。这是一个小型图书馆,进入它应该不难。
现在,我来这里的目的是,我正在尝试使用 lifegame 和 helm 来在屏幕上实际显示世代。这是我写的:
import FRP.Helm
import FRP.Helm.Graphics (Element(..))
import qualified FRP.Helm.Window as Window
import FRP.Helm.Animation (Frame, AnimationStatus(..), animate, absolute)
import FRP.Helm.Time (second, running, delta)
import FRP.Elerea.Simple
import Cell.Display (allGenFrames)
import LifeGame.Data.CellGrid (CellGrid(..), randCellGrid)
render :: Form -> (Int, Int) -> Element
render form (x, y) = collage x y $ [form]
main :: IO ()
main = do
cg <- randCellGrid 50 50
anim <- return . absolute $ allGenFrames cg (1 * second) 10
engine <- startup defaultConfig
run engine $ render <~ (animate anim running status) ~~ Window.dimensions engine
where
config = defaultConfig windowTitle = "bats"
, windowDimensions = (500, 500)
status = effectful $ getLine >>= \i -> return $
case i of
"Pause" -> Pause
"Stop" -> Stop
"Cycle" -> Cycle
(来自:github.com/qleguennec/bats.git)
计算的艰苦工作在animate running status
",第20行。我不太明白animate的第二个参数是什么。此外,我不确定提供无限的Frames列表是否合法。
当我启动代码时,游戏冻结并在 5 分钟后停止。它似乎消耗了所有内存并崩溃。现在,我知道所有这些都缺乏文档。我在做这个工作。但是,作为婴儿 Haskeller 和婴儿 FRP/SDL 开发人员,我需要知道我是否以错误的方式执行此操作(我可能会这样做)。 接受并推荐任何评论。谢谢。
【问题讨论】:
【参考方案1】:我不知道我能否在 FRP 方面为您提供帮助 - 有这么多库,我自己也没怎么玩过 - 但它的价值(因为你说你对 Haskell 很陌生), Conway's Life 不用 FRP 也能轻松写出,用 SDL 渲染也很简单。
我发现最好将游戏表示为一组坐标对,而不是一个数组 - 这样,您就没有边界条件或世界环绕问题。 (您可以从 hashmap
和 unordered-containers
包中获得高效的严格集或惰性集。
CA 逻辑如下所示:
next cs = [i | (i,n) <- M.toList neighbors,
n == 3 || (n == 2 && S.member i cs')]
where
cs' = S.fromList cs
moore (x,y) = tail $ liftM2 (,) [x, x+1, x-1] [y, y+1, y-1]
neighbors = M.fromListWith (+) $ map (,1) $ moore =<< cs
主程序循环如下所示:
run w cs = do
drawCells w cs
e <- pollEvent
case e of
KeyUp (Keysym SDLK_ESCAPE _ _) -> return ()
KeyUp (Keysym SDLK_SPACE _ _) -> pause w cs
_ -> run w $ next cs
drawCells w cs = do
fillRect w (Just $ Rect 0 0 xres yres) (Pixel 0)
c <- createRGBSurface [SWSurface] cellSz cellSz 32 0 0 0 0
mapM_ (draw c . scale) cs
SDL.flip w
where
rect (x,y) = Just $ Rect x y cellSz cellSz
scale = join (***) (* cellSz)
draw c p = do fillRect c Nothing $ Pixel 0xFFFFFF
blitSurface c Nothing w $ rect p
要查看完整的实现,以及 FRP 可以为您提供的大部分功能(通过鼠标编辑网格)等等,take a look at this.
【讨论】:
以上是关于Haskell 生命游戏在启动时崩溃的主要内容,如果未能解决你的问题,请参考以下文章