榆树游戏生活计划变得反应迟钝 - 有没有办法优雅地失败?

时间:2016-10-10 09:34:11

标签: elm conways-game-of-life

我有一个基本实现康威的生命游戏,用uminokirin.com运行的榆树写成。

来源可见here

该程序允许用户调整toroïdal网格的大小,单击单元格以更改其状态,并随机化世界。它适用于我的计算机上的小值(小于50)。

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

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

这是榆树运行时放弃了吗?还是某种浏览器保障?

更重要的是,有没有办法防止这种行为,而不是任意限制网格的最大大小?

1 个答案:

答案 0 :(得分:6)

您观察到的行为是由于Javascript堆栈溢出造成的。按下"随机化"按钮,在浏览器控制台中,您可以看到消息" Uncaught RangeError:超出最大调用堆栈大小"

这是因为randomize函数分配了几个大的临时变量。特别是,随机函数(从randomize函数调用)似乎分配了两个临时列表,每个临时列表对于生命网格中的每个单元都有一个元素。榆树可能会很及时地发布这些内容,但这似乎推动它太过分了。

要解决此问题,您可以使用更简单的随机化功能。下面显示的版本使用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

使用这个随机化功能,我能够将网格调整到600x600并成功随机化。那时我停止了测试。