slice()分解javascript生命游戏

时间:2018-02-28 03:19:36

标签: javascript html slice p5.js conways-game-of-life

我的问题是关于javascript中的slice()

我正在创造我的第一部生命游戏。它完成得非常快,但我马上就完成了 注意到它没有按预期工作。我一直在尝试调试它 几个小时和几个小时和它的种类。但它一直在困扰着我 是不是它首先打破了它...我改变的方式 几代人用某种奇怪的方式打破了整个逻辑,使它成为我的游戏 生活在一个奇怪的迷宫看起来模式中失去控制。它只是一个版本的 用户选择放入种子模式的生命游戏,然后单击上 放入屏幕并启动游戏。

 // Basic vars
    var width, height, life;

    // Seed vars
    var seedPlanted = false;  // Is the game on?
    var seedPos = {
      x: 0,
      y: 0
    };

    // Different seeds
    var acorn = [
      [0, 0, 1],
      [1, 0, 1],
      [0, 0, 0],
      [0, 1, 0],
      [0, 0, 1],
      [0, 0, 1],
      [0, 0, 1]
    ];
    var rPentomino = [
      [0, 1, 0],
      [1, 1, 1],
      [1, 0, 0]
    ];
    var dieHard = [
      [0, 1, 0],
      [0, 1, 1],
      [0, 0, 0],
      [0, 0, 0],
      [0, 0, 0],
      [0, 0, 1],
      [1, 0, 1],
      [0, 0, 1]
    ];
    var gosperGliderGun = [
      [0, 0, 0, 0, 1, 1, 0, 0, 0],
      [0, 0, 0, 0, 1, 1, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 1, 1, 1, 0, 0],
      [0, 0, 0, 1, 0, 0, 0, 1, 0],
      [0, 0, 1, 0, 0, 0, 0, 0, 1],
      [0, 0, 1, 0, 0, 0, 0, 0, 1],
      [0, 0, 0, 0, 0, 1, 0, 0, 0],
      [0, 0, 0, 1, 0, 0, 0, 1, 0],
      [0, 0, 0, 0, 1, 1, 1, 0, 0],
      [0, 0, 0, 0, 0, 1, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 1, 1, 1, 0, 0, 0, 0],
      [0, 0, 1, 1, 1, 0, 0, 0, 0],
      [0, 1, 0, 0, 0, 1, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [1, 1, 0, 0, 0, 1, 1, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 1, 1, 0, 0, 0, 0, 0],
      [0, 0, 1, 1, 0, 0, 0, 0, 0]
    ];
    var beeHive = [
      [0, 1, 0],
      [1, 0, 1],
      [1, 0, 1],
      [0, 1, 0]
    ];
    var loaf = [
      [0, 1, 0, 0],
      [1, 0, 1, 0],
      [1, 0, 0, 1],
      [0, 1, 1, 0]
    ];
    var toad = [
      [0, 1],
      [1, 1],
      [1, 1],
      [1, 0]
    ];

    // p5 canvas setup
    function setup() {
      width = windowWidth;
      height = windowHeight;
      createCanvas(width, height);
    }

    // Capture user click and set it as the seed position and start the game
    function mouseClicked() {
      if (!seedPlanted) {
        seedPos.x = mouseX;
        seedPos.y = mouseY;
        seedPlanted = true;
        life = new Life(gosperGliderGun, seedPos);  // Initiate the Life object
      }
    }

    // p5 draw
    function draw() {
      background(51);
      if (seedPlanted) {  // Check if the game is on
        life.generate();  // Generate a new generation
        life.display();   // Display the new generation
      }
    }

    // The Life object constuctor
    function Life(seed, pos) {
      this.cellWidth = 4;  // Width of the cells in px
      this.caWidth = Math.ceil(width / this.cellWidth);  // Calculate the grid Width
      this.caHeight = Math.ceil(height / this.cellWidth);// And grid height

      this.curGen = [];  // Declare an array for the current generation 

      // Fill the curGen with arrays full of 0's
      for (var i = 0; i < this.caWidth; i++) {
        this.curGen[i] = [];
        for (var j = 0; j < this.caHeight; j++) {
          this.curGen[i][j] = 0;
        }
      }

      // Apply the seed to the curGen
      pos.x = Math.round(pos.x / this.cellWidth);  // Convert seedPos from px to cells
      pos.y = Math.round(pos.y / this.cellWidth);
      for (var i = 0; i < seed.length; i++) {  // Place the seed to the curGen
        for (var j = 0; j < seed[i].length; j++) {
          this.curGen[(this.caWidth + pos.x + i) % this.caWidth][(this.caHeight + pos.y + j) % this.caHeight] = seed[i][j];
        }
      }

      // Create and fill the nextGen array variable with empty arrays
      this.nextGen = [];
      for (var i = 0; i < this.caWidth; i++) {
        this.nextGen[i] = [];
      }

      // Generate a new generation
      this.generate = function() {
        for (var i = 0; i < this.caWidth; i++) {  // Loop through the cells
          for (var j = 0; j < this.caHeight; j++) {
            var neighbors = 0;
            for (var k = -1; k <= 1; k++) { // At every cell, loop through its neighbors in a 3x3 grid
              for (var l = -1; l <= 1; l++) {
                // Count the neighbors and wrap aroundthe edges with "modulo trick"
                neighbors += this.curGen[(this.caWidth + i + k) % this.caWidth][(this.caHeight + j + l) % this.caHeight];
              }
            }
            neighbors -= this.curGen[i][j];  // Subract the cell itself from the neighbors

            // Rules of survival and birth
            if (this.curGen[i][j] === 1 && neighbors < 2) { // Underpopulation
              this.nextGen[i][j] = 0;
            } else if (this.curGen[i][j] === 1 && neighbors > 3) { // Overpopulation
              this.nextGen[i][j] = 0;
            } else if (this.curGen[i][j] === 0 && neighbors === 3) { // Reproduction
              this.nextGen[i][j] = 1;
            } else { // Stasis
              this.nextGen[i][j] = this.curGen[i][j];
            }
          }
        }

这是问题部分。现在我必须将新创建的一代设置为
当前一代,以便它将显示和生成。
我的第一个想法是使用slice()来切除来自的信息 新的nextGen并把它放在旧的curGen。然后我可以在下一个基础上写字 在下一轮。这似乎是一个像我一样的新手,但它创造了 一些奇怪的失控增长和消失。我经历了所有的循环
和数组,并在屏幕上绘制各种东西,以了解什么不是 工作。我发现邻居没有被计算在内,而且 它使像“蟾蜍”这样基本稳定的种子消失了。

然后我去了其他例子,其他人是如何做到的,这就是“交换” p5js.org中的方法生命游戏的例子引起了我的注意,你只需要交换
在一个临时变量的帮助下,世代将另一个变为另一个 时刻。不知怎的,这使得同样的逻辑起作用。我不明白为什么。
然后我尝试修复我的旧方法,只是在徒劳的nextGen上写0。 没工作。然后我试着把它写成全新的数组,它起作用了。我不 理解为什么交换方法有效,让其他阵列充满旧状态
等待被覆盖,并且slice()方法将相同的旧状态留给了 被覆盖到其他阵列不起作用。除非我写完全新的 阵列。 slice()函数是否会留下对旧数组或somehing的引用?

如果取消注释 FastFix 行,它将起作用,

或者如果取消注释三个“swap”方法行,并注释掉slice()
具有以下for循环的方法。它会工作。但不是只有slice()。

有人可以告诉我为什么吗? slice()做什么,“交换”没有?

  //var temp = this.curGen;             //
    //this.curGen = this.nextGen;         // Why this "swap" method works?
    //this.nextGen = temp;                //

    this.curGen = this.nextGen.slice(0);  // And this slice() not?

    for (var i = 0; i < this.caWidth; i++) {    // This
      //this.nextGen[i] = [];  //<---*FastFix*  // is all
      for (var j = 0; j < this.caHeight; j++) { // a fix that I
        this.nextGen[i][j] = 0;                 // that I tried.
      }                                         // But it wont
    }                                           // work without
  }                                             // the *FastFix*
                                                // which is a
                                                // stupid hack


 // Display the cells
  this.display = function() {
    for (var i = 0; i < this.caWidth; i++) {  // Loop through the cells
      for (var j = 0; j < this.caHeight; j++) {
        noStroke();
        if (this.curGen[i][j] == 1) {  // Decide fill based on the cell state
          fill(255);
        } else {
          fill(51);
        }
        rect(i * this.cellWidth, j * this.cellWidth, this.cellWidth, this.cellWidth);  // And draw it
      }
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/p5.js"></script>
<html>

<head>
  <meta charset="UTF-8">
  <script language="javascript" type="text/javascript" src="libraries/p5.js"></script>
  <script language="javascript" type="text/javascript" src="sketch.js"></script>
  <script language="javascript" type="text/javascript" src="life.js"></script>
  <style>
    body {
      padding: 0;
      margin: 0;
    }
  </style>
</head>

<body>
</body>

</html>

0 个答案:

没有答案