简体   繁体   English

康威的人口过剩游戏?

[英]Conway's Game of life overpopulation?

I was working on a Conway's game of life clone because it is good practice, but I ran into a problem. 我当时正在研究康威(Conway)的生活游戏,因为这是一种很好的做法,但我遇到了一个问题。 I see there are pixels deleting and rebirthing, but all the pixels just spread out the very end of the screen and then other pixels are rebirthing, but it is just idling at that point. 我看到有像素在删除和重生,但所有像素仅散布在屏幕的尽头,然后其他像素在重生,但此时只是空转。

Here are some screenshots: 以下是一些屏幕截图: 在此处输入图片说明

I'll show you some of my code for the logic of this. 我将向您展示一些有关此逻辑的代码。 It is all handled in the change method: 全部在change方法中处理:

package main;

import java.awt.Color;
import java.awt.Graphics;

public class Functions {

  public static int pixelsize=6,gridwidth=800/6,gridheight=600/6;
  static int[][] pixels = new int[gridwidth][gridheight];
  static boolean first = true;

  public static void change(){

    for(int i = 0; i < gridwidth; i++){
      for(int j = 0; j < gridheight; j++){
        int neighbors = 0;
        //check each cell

        try{

          if(pixels[i+1][j] == 1){neighbors++;}
          if(pixels[i-1][j] == 1){neighbors++;}
          if(pixels[i+1][j-1] == 1){neighbors++;}
          if(pixels[i][j+1] == 1){neighbors++;}
          if(pixels[i][j-1] == 1){neighbors++;}
          if(pixels[i+1][j+1] == 1){neighbors++;}
          if(pixels[i-1][j-1] == 1){neighbors++;}
          if(pixels[i-1][j+1] == 1){neighbors++;}

        }catch(ArrayIndexOutOfBoundsException e){

        }

        if(neighbors == 3 || neighbors == 2 ){
          pixels[i][j] = 1;
        }else if(neighbors < 2 || neighbors >= 4){
          pixels[i][j] = 0;
        }
      }
    }
  }

  public static void render(Graphics g){

    for(int i = 0; i < gridwidth;i++){
      for(int j = 0; j < gridheight; j++){
        if(pixels[i][j] == 1){

          g.setColor(Color.red);
          g.fillRect(i*6, j*6, 6, 6);
        }
      }
    }
  }
}


thanks for all the help. 感谢所有的帮助。 Sadly it still isn't working correctly. 遗憾的是,它仍然无法正常工作。
Now it is doing the same thing but in diamond formation like so: 现在它正在做同样的事情,但是像这样形成钻石:
在此处输入图片说明

The main problem I do see here is the fact that you are updating values while discovering them. 我在这里看到的主要问题是您在发现值时正在更新它们。

You should cache your whole grid (or at least neighbours count) before updating, otherwise, while you update element at (x, y) , you are alterating the neighbours count for element that are successive as (x+1,y) , (x+1,y+1) , (x,y+1) by counting the outcome of current iteration. 在更新之前,您应该缓存整个网格(或至少邻居数),否则,在更新元素(x, y) ,您将更改连续元素的邻居数(x+1,y)(x+1,y+1)(x,y+1)通过计算当前迭代的结果。

For example you could update a separate array called cachedPixels like so: 例如,您可以像这样更新一个单独的数组,称为cachedPixels:

for(int i = 0; i < gridwidth; i++){
    for(int j = 0; j < gridheight; j++){
        int neighbors = 0;
        // find the proper boundaries
        int minI = Math.max(0, i - 1);
        int maxI = Math.min(gridwidth, i + 2)
        int minJ = Math.max(0, j - 1);
        int maxJ = Math.min(gridheight, j + 2)

        for (int i2 = minI; i2 < maxI; i2++) {
           for (int j2 = minJ; j2 < maxJ; j2++) {
              if (i2 != i || j2 != j) {
                 if (pixels[i2][j2] == 1) {
                    neighbors++;
                 }
              }
           }
        }

        if (neighbors == 2 || neighbors == 3) {
           cachedPixels[i][j] = 1;
        } else {
           cachedPixels[i][j] = 0; // probably not even necessary as 0 is default value
        }
    }   
}

Then after completing this process for the entire array set using the arraycopy function: 然后,在使用arraycopy函数完成整个阵列集的此过程之后:

for (int i = 0; i < length; i++) {
    System.arraycopy(cachedPixels[i], 0, pixels[i], 0, cachedPixels[i].length);
}

Simply setting pixels = cachedPixels would point "pixels" to the "cachedPixels" array and so changing one would change the other, and the system would collapse. 简单地设置像素= cachedPixels会将“像素”指向“ cachedPixels”数组,因此更改一个将更改另一个,并且系统将崩溃。

PS The rules you're using for your GoL are not the same as John H. Conway's. PS您用于GoL的规则与John H. Conway的规则不同。 Cells always live on the next time step if they have 3 neighbours, and live on the next time step with 2 neighbours only if they are alive in this time step, else they die: 如果小区有3个邻居,它们始终生活在下一个时间步;只有在这个时间步中它们还活着,它们才会与2个邻居一起生活在下一时间步,否则它们将死亡:

cachedPixels[i][j] = 0; // Default value - death.
if (neighbors == 3) {
   cachedPixels[i][j] = 1;
} else if (thisCell == 1 && neighbors == 2) {
   cachedPixels[i][j] = 1;
}

Your newborn pixels should not be counted as neighbours for this move, and your dying pixels should be counted. 你的新生像素不应该算作邻居这一举动,和你死去的像素应该被计算在内。 It can be achieved by having another values, say 2 and 3 , for newborn and dying pixels. 对于新生像素和垂死像素,可以通过使用另一个值(例如23来实现。 After processing the field, you commit its state by replacing a value for newborn with 1 and a value for dying with 0 . 处理完字段后,通过将新生儿值替换为1并将死亡值替换为0 提交状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM