我有一个基本实现康威的生命游戏,用uminokirin.com运行的榆树写成。
来源可见here。
该程序允许用户调整toroïdal网格的大小,单击单元格以更改其状态,并随机化世界。它适用于我的计算机上的小值(小于50)。
然而,当尝试在更大的网格上使用随机化网格功能时(阈值似乎并不总是相同),程序变得没有响应而没有任何警告,唯一的恢复方法是重新加载应用程序。
GOL算法中没有优化,并且对每个单元格使用单个svg
矩形可能效率非常低,但它并不能解释为什么程序以这种方式运行而不是说减慢速度。
这是榆树运行时放弃了吗?还是某种浏览器保障?
更重要的是,有没有办法防止这种行为,而不是任意限制网格的最大大小?
答案 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并成功随机化。那时我停止了测试。