使用
我在用 JavaScript 实现 Conway 的生命游戏时遇到了一些问题。在德语维基百科中,它说这种模式在这里:
54代后将创建一个空世界,演变如下:
也就是说,第二代看起来像这样:
但是当使用我的代码时,第二代看起来像这样,世界也没有变空:
所以我的代码显然是错误的,但我没有看到我的错误:
var cellSize = 5, // In px
fieldSize = 70, // In cells
canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
thisGeneration = [],
nextGeneration = [];
// Set canvas size
canvas.width = canvas.height = cellSize * fieldSize;
// Fill the generation array
for (var i = 0; i < fieldSize; i++){
thisGeneration.push([]);
for (var x = 0; x < fieldSize; x++){
// thisGeneration[thisGeneration.length-1].push( (Math.random() > 0.08)? 0 : 1);
thisGeneration[thisGeneration.length-1].push(0);
}
}
// Draw pattern:
thisGeneration[35][35] = thisGeneration[35][36] = thisGeneration[35][37] =
thisGeneration[36][35] = thisGeneration[36][37] =
thisGeneration[37][35] = thisGeneration[37][37] =
thisGeneration[39][35] = thisGeneration[39][37] =
thisGeneration[40][35] = thisGeneration[40][37] =
thisGeneration[41][35] = thisGeneration[41][36] = thisGeneration[41][37] =
1;
// "slice" causes "nextGeneration" to be a copy, not a reference
nextGeneration = thisGeneration.slice(0);
setInterval(function(){
for (var y = 0, l = thisGeneration.length, x, l2, n; y < l; y++){
for (x = 0, l2 = thisGeneration[y].length; x < l2; x++){
ctx.fillStyle = thisGeneration[y][x]? "black" : "white";
ctx.fillRect(x*cellSize, y*cellSize, cellSize, cellSize);
// n := Number of neighbors of the cell
n = 0;
if (typeof (thisGeneration[y-1]) != "undefined"){
n += (
(thisGeneration [y-1] [x-1] ||0)+
(thisGeneration [y-1] [ x ] ||0)+
(thisGeneration [y-1] [x+1] ||0)
);
}
n += (
(thisGeneration [ y ] [x-1] ||0)+
(thisGeneration [ y ] [x+1] ||0)
);
if (typeof (thisGeneration[y+1]) != "undefined"){
n += (
(thisGeneration [y+1] [x-1] ||0)+
(thisGeneration [y+1] [ x ] ||0)+
(thisGeneration [y+1] [x+1] ||0)
);
}
if (n === 3 && !thisGeneration[y][x]){
// Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
nextGeneration[y][x] = 1;
}
if (n < 2 && thisGeneration[y][x]){
// Any live cell with fewer than two live neighbours dies, as if caused by under-population.
nextGeneration[y][x] = 0;
}
if ((n === 2 || n === 3) && thisGeneration[y][x]){
// Any live cell with two or three live neighbours lives on to the next generation.
nextGeneration[y][x] = 1;
}
if (n > 3 && thisGeneration[y][x]){
// Any live cell with more than three live neighbours dies, as if by overcrowding.
nextGeneration[y][x] = 0;
}
}
}
thisGeneration = nextGeneration.slice(0); // "slice" causes "thisGeneration" to be a copy, not a reference
}, 1000);
我还想知道是否可以提高脚本的性能,因为你可以看到我使用二维数组保存单元格状态。
I've got some problems implementing Conway's Game of Life in JavaScript. At the German Wikipedia it says that this pattern here:
Will create an empty world after 54 generations and the evolution looks like this:
That means, the second generation looks like this:
But when using my code, the second generation looks like this and the world doesn't get empty, either:
So my code is obviously wrong, but I don't see my mistake:
var cellSize = 5, // In px
fieldSize = 70, // In cells
canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
thisGeneration = [],
nextGeneration = [];
// Set canvas size
canvas.width = canvas.height = cellSize * fieldSize;
// Fill the generation array
for (var i = 0; i < fieldSize; i++){
thisGeneration.push([]);
for (var x = 0; x < fieldSize; x++){
// thisGeneration[thisGeneration.length-1].push( (Math.random() > 0.08)? 0 : 1);
thisGeneration[thisGeneration.length-1].push(0);
}
}
// Draw pattern:
thisGeneration[35][35] = thisGeneration[35][36] = thisGeneration[35][37] =
thisGeneration[36][35] = thisGeneration[36][37] =
thisGeneration[37][35] = thisGeneration[37][37] =
thisGeneration[39][35] = thisGeneration[39][37] =
thisGeneration[40][35] = thisGeneration[40][37] =
thisGeneration[41][35] = thisGeneration[41][36] = thisGeneration[41][37] =
1;
// "slice" causes "nextGeneration" to be a copy, not a reference
nextGeneration = thisGeneration.slice(0);
setInterval(function(){
for (var y = 0, l = thisGeneration.length, x, l2, n; y < l; y++){
for (x = 0, l2 = thisGeneration[y].length; x < l2; x++){
ctx.fillStyle = thisGeneration[y][x]? "black" : "white";
ctx.fillRect(x*cellSize, y*cellSize, cellSize, cellSize);
// n := Number of neighbors of the cell
n = 0;
if (typeof (thisGeneration[y-1]) != "undefined"){
n += (
(thisGeneration [y-1] [x-1] ||0)+
(thisGeneration [y-1] [ x ] ||0)+
(thisGeneration [y-1] [x+1] ||0)
);
}
n += (
(thisGeneration [ y ] [x-1] ||0)+
(thisGeneration [ y ] [x+1] ||0)
);
if (typeof (thisGeneration[y+1]) != "undefined"){
n += (
(thisGeneration [y+1] [x-1] ||0)+
(thisGeneration [y+1] [ x ] ||0)+
(thisGeneration [y+1] [x+1] ||0)
);
}
if (n === 3 && !thisGeneration[y][x]){
// Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
nextGeneration[y][x] = 1;
}
if (n < 2 && thisGeneration[y][x]){
// Any live cell with fewer than two live neighbours dies, as if caused by under-population.
nextGeneration[y][x] = 0;
}
if ((n === 2 || n === 3) && thisGeneration[y][x]){
// Any live cell with two or three live neighbours lives on to the next generation.
nextGeneration[y][x] = 1;
}
if (n > 3 && thisGeneration[y][x]){
// Any live cell with more than three live neighbours dies, as if by overcrowding.
nextGeneration[y][x] = 0;
}
}
}
thisGeneration = nextGeneration.slice(0); // "slice" causes "thisGeneration" to be a copy, not a reference
}, 1000);
I'd also like to know whether I could improve the performance of the script, because as you can see I use a 2-dimensional array save the cell states.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不认为这一代和下一代像你想象的那样独立。我建议您用逐个单元复制替换切片操作,看看是否可以解决问题。
I don't think that thisGeneration and nextGeneration are as independent as you think they are. I suggest you replace the slice operations with a cell by cell copy and see if that resolves things.