这是我第一次尝试在Javascript项目中使用类 - 我正在尝试在HTML5 Canvas中实现Conway的生命游戏。 Here's the code.正如您所看到的,第一代渲染很好,但next()
函数出现了问题,导致它无法再运行。 (我确实注意到有问题的错误实际上是在get()
的最后一行抛出的,这是由neighbors()
调用的函数之一,由next()
调用。我不能在任一函数中发现任何问题,但显然某事错误!)
答案 0 :(得分:3)
问题是[关于%
的假设是错误的,因此get/set
函数中的警卫不能按预期工作:
-1 % 42 // results in -1
快乐的编码。
我会考虑移除 get/set
函数中的警卫并使用sentinel values(或其他邻居边缘框)作为边框(例如第一行/最后一行和列永远不会实际绘制到屏幕上。)
这可以避免大量的后卫检查 - get/set
每次迭代都会被称为一大堆(我甚至都没有它们作为功能)。我认为删除get/set
和守卫“没问题”因为这些操作是进程的内部操作并且与算法密切相关 - 它们不是直接公开的,而JavaScript只是如此之快。
每个周期执行“全网格邻居检查”为C * O(h*w)
。虽然它具有相同的复杂性,但是明显更小的C
可以使程序运行得更快。
答案 1 :(得分:1)
你在next
:
for(var y = 0; y < this.height; y++){
for(var x = 0; x < this.width; x++){
newMap[x][y] = this.get(x, y);
//Rule 1: any live cell with fewer than two live neighbors dies
if(this.get(x, y) == true && this.neighbors(x, y) < 2){
newMap[x][y] = false;
}
//...
所以在第一次迭代中,x
和y
为零。现在看看neighbors
正在做什么:
this.neighbors = function(x, y){
n = 0;
//...
if(this.get(x-1, y-1)){n++;}
//...
return n;
}
如果x
和y
为0
,则会尝试检查单元格(-1,-1)
:
this.map[x][y] = val;
但是你的map
只有正整数键。
如果您想“环绕”,请增加get
中的值以避免负值:
x = (x + this.width) % this.width;
y = (y + this.height) % this.height;
答案 2 :(得分:1)
该行
x = x % this.width;
无法正常工作:
-1 % 640
给出
-1
轻松修复:
x = (x + this.width) % this.width;
答案 3 :(得分:1)
让我们检查第一个细胞。假设x
为0且y
为0.在处理该单元格期间,您最终会检查this.map[-1][-1]
。由于this.map[-1]
未定义,因此您无法在其中找到元素-1,即使它确实存在(它不存在)。
您有几个选择:
x > 0
,然后在抓取右侧任何内容之前x < this.width - 1
。 y
和this.height
的相似故事。this.map[x - 1]
或this.map[x + 1]
。与y +/- 1
相同 - 如果未定义,请将其视为假。this.map[-1]
和this.map[whatever][-1]
定义为false,以及this.map[this.width]
和this.map[whatever][this.height]
。x - 1
变为(x + width - 1) % width
。与y - 1
相同。那应该让地图环绕。