我正在研究康威的生命克隆游戏因为这是一个好习惯,但我遇到了一个问题。我看到有像素删除和重生,但所有像素只是展开在屏幕的最后,然后其他像素重生,但它只是空转。
以下是一些截图:
我将向您展示我的一些逻辑代码。它全部用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);
}
}
}
}
}
感谢所有的帮助。可悲的是,它仍然无法正常工作。
现在它正在做同样的事情,但钻石形成是这样的:
答案 0 :(得分:6)
我在这里看到的主要问题是你在发现它们时正在更新值。
您应该在更新之前缓存整个网格(或至少是邻居计数),否则,当您更新(x, y)
处的元素时,您将更改连续为(x+1,y)
的元素的邻居计数, (x+1,y+1)
,(x,y+1)
通过计算当前迭代的结果。
例如,您可以更新一个名为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
}
}
}
然后使用arraycopy函数完成整个数组的此过程:
for (int i = 0; i < length; i++) {
System.arraycopy(cachedPixels[i], 0, pixels[i], 0, cachedPixels[i].length);
}
简单设置pixels = cachedPixels会将“像素”指向“cachedPixels”数组,因此更改一个会改变另一个,系统会崩溃。
P.S。您用于GoL的规则与John H. Conway的规则不同。如果单元格有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;
}
答案 1 :(得分:2)
不应将您的新生像素计算为此移动的邻居,并且应计算您的垂死像素 。可以通过为新生和垂死像素设置另一个值(例如2
和3
)来实现。处理完字段后,您可以通过使用1
替换为新生儿的值和使用0
进行死亡的值来提交其状态。