对于一个有趣的小项目,我决定用javascript编写conway的生活游戏。我的逻辑似乎有意义,每个单独的功能都能完成它的工作但是我仍然没有得到我想要的结果。我有一个名为grid的数组,它存储所有单元格的值,如果它们存活或死亡。我检查每个单独的单元格,然后检查所有8个周围的单元格以计算邻居,重复每个其他单元格。在某些时候,我的网格不再存储正确的值并重置。在这一点上,我开始认为这是一个JavaScript问题。
<body>
<style>
* {
padding: 0;
margin: 0;
}
body {
overflow: hidden;
}
canvas {
background: #FFFFFF;
display: block;
margin: 0 auto;
}
</style>
<canvas id="canvas" style="border:1px solid #000000;"></canvas>
</body>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var Game = {};
var nextGrid, emptyGrid, grid;
Game.horCells = 30;
Game.cellSize = canvas.width / Game.horCells;
Game.verCells = Math.floor(canvas.height / Game.cellSize);
Game.startLives = 80;
config();
//setInterval(run, 1000);
function config() {
console.log("in config");
emptyGrid = newGrid(Game.horCells, Game.verCells);
grid = emptyGrid;
nextGrid = emptyGrid;
//Manual Setup
for (var i = 0; i < Game.startLives; i++) {
//grid[getRandomInt(0, Game.horCells - 1)][getRandomInt(0, Game.verCells - 1)] = true;
}
grid[0][3] = true;
grid[1][3] = true;
grid[2][3] = true;
}
function run() {
console.log("gread" + grid[3][3]);
draw();
update();
}
function draw() {
console.log("Draw");
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < Game.horCells; i++) {
for (var j = 0; j < Game.verCells; j++) {
if (grid[i][j] === false) {
ctx.fillStyle = "#FFFFFF";
} else if (grid[i][j] === true) {
console.log("drawing live");
ctx.fillStyle = "#000000";
}
ctx.fillRect(i * Game.cellSize, j * Game.cellSize, Game.cellSize, Game.cellSize);
}
}
}
function update() {
for (var p = 0; p < Game.horCells; p++) {
for (var k = 0; k < Game.verCells; k++) {
nextGrid[p][k] = survival(p, k);
}
}
}
function survival(x, y) {
var neighbours = 0;
for (var l = 0; l < 3; l++) {
for (var m = 0; m < 3; m++) {
var sx = (x - 1) + l;
var sy = (y - 1) + m;
//Check bounds
if (inBounds(sx, sy) === true && grid[sx][sy]) {
neighbours++;
}
}
}
if (grid[x][y]) {
neighbours--;
if (neighbours === 2 || neighbours === 3) {
return true;
} else if (neighbours < 2 || neighbours > 3) {
console.log("DIED");
return false;
}
} else if (grid[x][y] === false && neighbours === 3) {
return true;
} else {
console.log("DIED");
return false;
}
}
function inBounds(x, y) {
return (x >= 0 && x < Game.horCells && y >= 0 && y < Game.horCells);
}
function newGrid(xCells, yCells) {
var gridd = new Array(xCells);
for (var i = 0; i < xCells; i++) {
gridd[i] = new Array(yCells);
}
for (var j = 0; j < xCells; j++) {
for (var k = 0; k < yCells; k++) {
gridd[j][k] = false;
}
}
return gridd;
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
</script>
答案 0 :(得分:0)
emptyGrid = newGrid(Game.horCells, Game.verCells);
grid = emptyGrid;
nextGrid = emptyGrid
创建 1 网格,然后将grid
和nextGrid
分配给同一对象。同样,grid
和nextGrid
是同一个对象。您对1所做的任何更改都将发生在另一方。
创建2个单独的网格,以便可以单独更改它们:
grid = newGrid(Game.horCells, Game.verCells);
nextGrid = newGrid(Game.horCells, Game.verCells);
或者,稍微加强它:
var g = () => newGrid(Game.horCells, Game.verCells);
grid = g();
nextGrid = g();
只是为了澄清评论中的问题:
var g = () => newGrid(Game.horCells, Game.verCells);
与(基本上)相同:
var g = function() {
return newGrid(Game.horCells, Game.verCells);
}
它被称为&#34;胖箭&#34;功能。
两个位都做同样的事情:它们创建一个返回新网格的函数。这样做的好处是不需要两次写newGrid(Game.horCells, Game.verCells);
。
我使用了箭头函数而不是function
关键字,因为后者是巨大且丑陋的,这使得清除代码的目标消失了。