康威(Conway)生活游戏中的更新功能无法正常运行

时间:2018-12-09 05:03:13

标签: javascript cellular-automata

我正在尝试用JavaScript制作Conway的《人生游戏》,但是经过数小时的调试,却找不到特定功能的问题。

该程序通过创建一个基于全局“行”和“列”变量的2D数组来工作,然后将“ Square”对象推入数组中的每个空间。然后,程序将“绘制”功能的间隔设置为特定间隔(全局变量“比率”)。

如果这很难理解,我深表歉意,但是基本上,每个特定的时间间隔(例如每1000毫秒),程序都会检查数组中的每个“ Square”对象,更新其拥有的邻居数量,然后在其上进行绘制屏幕。

这就是我被困住的地方;更新功能应该检查一个正方形具有的所有8个邻居(如果是边缘正方形则检查3-5个),但它只会检查4个邻居。无论我做什么,如果我单击一个正方形来填充它,则只有现在填充的正方形的顶部,左上角,右上角和左邻居会记录其邻居已被填充。

除了此bug之外,代码还可以正常工作,我99%确信问题出在这一功能上,因为该代码目前仍将充当自动机,而不是作为Conway的《生命游戏》。

var canvas = document.getElementById("life");
var ctx = canvas.getContext('2d');
var timer;
var rate = 1000;
var rows = 20;
var columns = 20;
var width = 20;
var clickX;
var clickY;
var board;
var running = false;
var checkArray = [
  [-1, 0, 1, 1, 1, 0, -1, -1],
  [-1, -1, -1, 0, 1, 1, 1, 0]
];
var visuals = true;
var gridColor = "#000000";
/*
live cell with < 2 neighbors = death
live cell with 2 or 3 neighbors = live for 1 generation
live cell with > 4 neighbors = death
dead cell with 3 neighbors = live for 1 generation
      
0 = death
1 = death
2 = continues life if alive
3 = continues life if alive OR brings to life if dead
4 = death
5 = death
6 = death
7 = death
8 = death
*/
window.onload = function() {
  makeBoard();
  var timer = setInterval(draw, rate);
  window.addEventListener("mousedown", clickHandler);
  // for(var i = 0; i < 8; i++){
  //     var checkIndexX = checkArray[0][i];
  //     var checkIndexY = checkArray[1][i];
  //   console.log(checkIndexX, checkIndexY);
  // }
}

function makeBoard() {
  board = new Array(columns);
  for (var i = 0; i < rows; i++) {
    var intRow = new Array(rows);
    for (var j = 0; j < columns; j++) {
      intRow[j] = new Square(false, j, i);
    }
    board[i] = intRow;
  }
}

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  for (var y = 0; y < rows; y++) {
    for (var x = 0; x < columns; x++) {
      if (running) {
        board[y][x].update();
      }
      board[y][x].draw();
      if (visuals) {
        board[y][x].visuals();
      }
    }
  }
  drawRunButton();
}

function Square(alive, PARX, PARY) {
  this.alive = false;
  this.X = PARX;
  this.Y = PARY;
  this.neighbors = 0;

  this.update = function() {
    this.neighbors = 0;
    for (var i = 0; i < 8; i++) {
      var checkIndexX = checkArray[0][i];
      var checkIndexY = checkArray[1][i];
      if ((this.X + checkIndexX) >= 0 && (this.X + checkIndexX) < columns &&
        (this.Y + checkIndexY) >= 0 && (this.Y + checkIndexY) < rows) {
        var check = board[this.Y + checkIndexY][this.X + checkIndexX];
        // console.log(this.X, this.Y, check.X, check.Y, checkIndexX, checkIndexY);
        if (check.alive) {
          this.neighbors++;
        }
      }
    }
    if (this.alive) {
      if (this.neighbors < 2 || this.neighbors > 3) {
        this.alive = false;
      }
    } else {
      if (this.neighbors == 3) {
        this.alive = true;
      }
    }
  };
  this.visuals = function() {
    drawVisuals(this.neighbors, this.X * width, this.Y * width);
  };
  this.draw = function(alive) {
    drawSquare(this.alive, this.X * width, this.Y * width, width);
  }
}

function clickHandler(e) {
  var clickX = e.screenX - 68;
  var clickY = e.screenY - 112;
  mapClick(clickX, clickY);
  manageRun(clickX, clickY);
}

function mapClick(x, y) {
  var indexX = Math.floor(x / width);
  var indexY = Math.floor(y / width);
  if (indexX >= 0 && indexX < columns && indexY >= 0 && indexY < rows) {
    board[indexY][indexX].alive = true;
  }
}

function manageRun(x, y) {
  if (x >= (columns * width) + 5 && x <= (columns * width) + 45 && y >= 5 && y <= 45) {
    if (running) {
      running = false;
    } else {
      running = true;
    }
    console.log(running);
  }
}

function drawRunButton() {
  drawSquare(false, (columns * width) + 5, 5, 40)
}

function drawSquare(fill, x, y, width) {
  ctx.beginPath();
  ctx.moveTo(x, y);
  ctx.lineTo(x + width, y);
  ctx.lineTo(x + width, y + width);
  ctx.lineTo(x, y + width);
  ctx.lineTo(x, y);
  if (fill) {
    ctx.fillStyle = gridColor;
    ctx.fill();
  } else {
    ctx.strokeStyle = gridColor;
    ctx.stroke();
  }
}

function drawVisuals(neighbors, x, y) {
  ctx.beginPath();
  ctx.fillStyle = "#ff0000";
  ctx.font = '20px serif';
  ctx.fillText(neighbors, x + (width / 3), y + (width / 1.25));
}
<!DOCTYPE html>
<html>

<head>
  <title>template.com</title>
  <link href="style.css" type="text/css" rel="stylesheet">
</head>

<body>
  <canvas id="life" width="1400" height="700" style="border: 1px solid black"></canvas>

</body>

</html>

0 个答案:

没有答案