我正在用P5JS编写Conways的生活游戏,但遇到了一个奇怪的错误。似乎“起作用”,但看起来全错了。我不确定是否与查找邻居无关,因为当我手动调用该函数时,它会起作用。我什至在其中复制了互联网的第二个邻居计数功能,它也起作用。
也许这是视觉上的故障,但我也不确定,因为代码看起来不错。
/// <reference path="../TSDef/p5.global-mode.d.ts" />
let gridSize = 10;
let arrCurrent = create2dArray(gridSize);
let arrNext = create2dArray(gridSize);
function setup() {
createCanvas(800, 800, WEBGL);
background(0);
stroke(0, 255, 0);
noFill();
initGame();
}
function draw() {
displayCells();
calcNextGen();
}
//Returns a 2D Array
function create2dArray(size) {
let newArray = new Array(size);
for (let i = 0; i < newArray.length; i++) {
newArray[i] = new Array(1);
}
return newArray;
}
//Fills initial array with random values
function initGame() {
for (let x = 0; x < arrCurrent.length; x++) {
for (let y = 0; y < arrCurrent.length; y++) {
arrCurrent[x][y] = Math.round((Math.random()));
}
}
}
//Calculates next generation
function calcNextGen() {
for (let x = 0; x < gridSize; x++) {
for (let y = 0; y < gridSize; y++) {
let neighbors = countNeighbors1(arrCurrent, x, y);
let state = arrCurrent[x][y];
//If cell is dead and has exactly 3 neighbors, it starts living
if (state === 0 && neighbors === 3) {
arrNext[x][y] = 1;
}
//If cell lives and has too few or too many neighbors, it dies
else if (state === 1 && (neighbors < 2 || neighbors > 3)) {
arrNext[x][y] = 0;
}
else {
arrNext[x][y] = state;
}
}
}
arrCurrent = arrNext.slice();
}
//Count neighbors
function countNeighbors(x, y) {
return arrCurrent[(x + 1) % gridSize][y] +
arrCurrent[x][(y + 1) % gridSize] +
arrCurrent[(x + gridSize - 1) % gridSize][y] +
arrCurrent[x][(y + gridSize - 1) % gridSize] +
arrCurrent[(x + 1) % gridSize][(y + 1) % gridSize] +
arrCurrent[(x + gridSize - 1) % gridSize][(y + 1) % gridSize] +
arrCurrent[(x + gridSize - 1) % gridSize][(y + gridSize - 1) % gridSize] +
arrCurrent[(x + 1) % gridSize][(y + gridSize - 1) % gridSize];
}
function countNeighbors1(grid, x, y) {
let sum = 0;
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
let col = (x + i + gridSize) % gridSize;
let row = (y + j + gridSize) % gridSize;
sum += grid[col][row];
}
}
sum -= grid[x][y];
return sum;
}
function displayCells() {
background(0);
translate(-300, -300, 0);
for (let x = 0; x < arrCurrent.length; x++) {
for (let y = 0; y < arrCurrent.length; y++) {
push();
translate(x * 50, y * 50, 0);
if (arrCurrent[x][y] === 1) box(50);
pop();
}
}
}
function logGrid() {
console.log(arrCurrent[0]);
console.log(arrCurrent[1]);
console.log(arrCurrent[2]);
console.log(arrCurrent[3]);
console.log(arrCurrent[4]);
console.log(arrCurrent[5]);
console.log(arrCurrent[6]);
console.log(arrCurrent[7]);
console.log(arrCurrent[8]);
console.log(arrCurrent[9]);
}
我知道我已经很近了,但是两个小时以来我一直在朝这个方向撞头。
这里有P5JS Web Editor,您可以复制代码并直观地看到问题。
感谢您的帮助-谢谢!
arrCurrent = arrNext.slice();
不会创建网格的深层副本,它只会创建第一维的浅层副本。它创建一个网格,其中arrCurrent
的列引用arrNext
的行。
您必须创建一个全新的网格:
arrCurrent = []
for (let x = 0; x < gridSize; x++)
arrCurrent.push(arrNext[x].slice());
let gridSize = 10;
let arrCurrent = create2dArray(gridSize);
let arrNext = create2dArray(gridSize);
function setup() {
createCanvas(800, 800, WEBGL);
background(0);
stroke(0, 255, 0);
noFill();
initGame();
frameRate(10)
}
function draw() {
displayCells();
calcNextGen();
}
//Returns a 2D Array
function create2dArray(size) {
let newArray = new Array(size);
for (let i = 0; i < newArray.length; i++) {
newArray[i] = new Array(1);
}
return newArray;
}
//Fills initial array with random values
function initGame() {
for (let x = 0; x < arrCurrent.length; x++) {
for (let y = 0; y < arrCurrent.length; y++) {
arrCurrent[x][y] = Math.round((Math.random()));
}
}
}
//Calculates next generation
// - A live cell dies if it has fewer than two live neighbors.
// - A live cell with two or three live neighbors lives on to the next generation.
// - A live cell with more than three live neighbors dies.
// - A dead cell will be brought back to live if it has exactly three live neighbors.
function calcNextGen() {
for (let x = 0; x < gridSize; x++) {
for (let y = 0; y < gridSize; y++) {
let neighbors = countNeighbors1(arrCurrent, x, y);
let state = arrCurrent[x][y];
//If cell is dead and has exactly 3 neighbors, it starts living
if (state === 0 && neighbors === 3) {
arrNext[x][y] = 1;
}
//If cell lives and has too few or too many neighbors, it dies
else if (state === 1 && (neighbors < 2 || neighbors > 3)) {
arrNext[x][y] = 0;
}
else {
arrNext[x][y] = state;
}
}
}
arrCurrent = []
for (let x = 0; x < gridSize; x++)
arrCurrent.push(arrNext[x].slice());
}
function countNeighbors1(grid, x, y) {
let sum = 0;
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
let col = (x + i + gridSize) % gridSize;
let row = (y + j + gridSize) % gridSize;
sum += grid[col][row];
}
}
sum -= grid[x][y];
return sum;
}
function displayCells() {
background(0);
translate(-75, -75, 0);
stroke(128);
box(50*gridSize, 50*gridSize, 50);
translate(-225, -225, 0);
stroke(0, 255, 0);
for (let x = 0; x < arrCurrent.length; x++) {
for (let y = 0; y < arrCurrent.length; y++) {
push();
translate(x * 50, y * 50, 0);
if (arrCurrent[x][y] === 1) box(50);
pop();
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>