榆树游戏的生活程序变得没有反应——有一种方法可以优雅地失败吗?



我在uminokirin.com上有一个用elm编写的康威生活游戏的基本实现。

源代码在这里可见。

该程序允许用户调整toroïdal网格的大小,单击单元格以改变其状态,并随机化世界。在我的电脑上,它可以很好地处理小数值(小于50)。

然而,当试图在更大的网格上使用随机网格函数时(阈值似乎并不总是相同),程序在没有任何警告的情况下变得无响应,唯一的恢复方法是重新加载应用程序。

在GOL算法中没有优化,并且对每个单元使用单个svg矩形可能非常低效,但它仍然不能解释为什么程序以这种方式而不是减慢速度。

这是榆树运行时放弃吗?或者某种浏览器保护?

更重要的是,有没有一种方法可以防止这种行为,而不是随意限制网格的最大大小?

您正在观察的行为是由于Javascript堆栈溢出。按下"randomize"按钮后,在浏览器控制台上你可以看到消息"Uncaught RangeError: Maximum call stack size exceeded"

这是因为randomize函数分配了几个大的临时变量。特别是,shuffle函数(从randomize函数调用)似乎分配了两个临时列表,每个列表对于生命网格中的每个单元都有一个元素。Elm在及时发布这些内容方面可能很聪明,但这似乎做得太过分了。

要解决这个问题,可以使用一个更简单的随机化函数。下面显示的版本使用Elm Generators生成Dead/Alive值的单个列表,然后从该列表初始化随机数组。

randomize2 : Array Cell -> Int -> Int -> Int -> Array Cell
randomize2 grid gs sd n = 
  let floatGen = Random.float 0.0 1.0
      lifeGen = Random.map (b -> if (b < toFloat n/100) then Alive else Dead) floatGen
      listGen = Random.list (gs*gs) lifeGen
  in fst (Random.step listGen (initialSeed sd)) |> fromList

使用这个randomize函数,我能够将网格的大小调整到600x600,并成功地随机化。这时,我停止了测试。

相关内容

最新更新