[英]conway's game of life doesn't work as expected
I was trying to create conway's game of live in java. 我试图在Java中创建conway的现场游戏。 I've no trouble with my code, but with the output of the game.
我的代码没有问题,但游戏的输出却没有问题。 The still lifes pattern work as expected, but all the moving sructures are ending up in something different.
静物模式按预期工作,但是所有移动的结构都以不同的方式结束。
For example: 1 is a living cell; 例如:1是活细胞; 0 is a dead cell
0是一个死单元
On the wiki page there is an oscillator, the blinker. 在Wiki页面上,有一个振荡器,即闪烁器。 in my case it behaves like this:
就我而言,它的行为如下:
I'm doing all the stuff in an applet, which i add to a jframe. 我正在将小程序中的所有内容都添加到jframe中。 Here's the applet code (ignore the german comments, unless you're german :P):
这是小程序代码(忽略德语注释,除非您是德语:P):
import java.applet.Applet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class Canvas extends Applet implements MouseListener{
private static final long serialVersionUID = -9195952699213522986L;
private boolean[][] cells; //True lebt; false ist tod
private int cellWidth;
private int margin = 2;
private int step = 0;
private boolean isRunning = false;
public Canvas(int size, int cv){ //size = 50; cv = 10;
addMouseListener(this);
cells = new boolean[size][size];
cellWidth = cv;
//Zellen Füllen
for(int i = 0; i < cells.length; i++){
for(int j = 0; j < cells[0].length; j++){
cells[i][j] = false;
}
}
}
@Override
public void paint(Graphics g){
//Updaten
if(isRunning)
update();
//Hintergrund
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
//Punkte zeichnen
for(int i = 0; i < cells.length; i++){
for(int j = 0; j < cells[0].length; j++){
if(cells[i][j]){
g.setColor(Color.GREEN);
g.fillRect(i * cellWidth + margin, j * cellWidth + margin, cellWidth - margin, cellWidth - margin);
}
else if(!cells[i][j]){
g.setColor(new Color(0x222222));
g.fillRect(i * cellWidth + margin, j * cellWidth + margin, cellWidth - margin, cellWidth - margin);
}
}
}
repaint();
}
private void update(){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Für jede Zelle Spielregeln anwenden ( siehe Wikipedia: http://de.wikipedia.org/wiki/Conways_Spiel_des_Lebens )
//Wichtig:
//Die Matrix muss komplett bearbeitet und neu gespeichert werden, deswegen newCells
boolean[][] newCells = cells.clone();
for(int i = 0; i < cells.length; i++){
for(int j = 0; j < cells[0].length; j++){
//Nachbarn
int neighbors = countNeighbors(i, j);
//Lebende Zelle
if(cells[i][j]){
//Einsamkeit
if(neighbors < 2){
newCells[i][j] = false;
}
//Überbevölkerung
else if(neighbors > 3){
newCells[i][j] = false;
}
//alles ok
else if(neighbors == 2 || neighbors == 3){
newCells[i][j] = true;
}
}
//Tote Zelle
else if(!cells[i][j]){
//Neue Zellen wird geboren
if(neighbors == 3){
newCells[i][j] = true;
}
}
}
}
cells = newCells;
System.out.println("Step #" + (++step));
}
private int countNeighbors(int x, int y){
int neighbors = 0;
for(int i = x-1; i <= x+1; i++){
for(int j = y-1; j <= y+1; j++){
if(x == i && y == j) //Dieselbe Zelle
continue;
try{
if(cells[i][j])
neighbors++;
} catch(java.lang.ArrayIndexOutOfBoundsException e){
}
}
}
return neighbors;
}
//Double Buffering
@Override
public void update(Graphics g){
Graphics offgc;
Image offscreen = null;
Dimension d = getSize();
// create the offscreen buffer and associated Graphics
offscreen = createImage(d.width, d.height);
offgc = offscreen.getGraphics();
// clear the exposed area
offgc.setColor(getBackground());
offgc.fillRect(0, 0, d.width, d.height);
offgc.setColor(getForeground());
// do normal redraw
paint(offgc);
// transfer offscreen to window
g.drawImage(offscreen, 0, 0, this);
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
if(e.isMetaDown()){
isRunning = !isRunning;
}
else if(!isRunning){
int x = e.getX() / cellWidth;
int y = e.getY() / cellWidth;
cells[x][y] = !cells[x][y];
}
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
}
It is a complex algorithm so I can't ensure you that it will work after this, but the rest of the code looks ok. 这是一个复杂的算法,所以我不能保证在此之后它会起作用,但是其余的代码看起来还可以。
boolean[][] newCells = cells.clone();
Ok, clone() performs a shadow copy which works well for primitives. 好的,clone()执行一个卷影副本,该卷影副本非常适合基元。 But it does not work for a bidimensional array (which acts as a onedimensional array of onedimensional arrays).
但是它不适用于二维数组 (充当一维数组的一维数组)。 So, you have still a shallow copy.
因此,您的副本仍然很浅。
After doing that, you are really overwritting the old array before all the calculations are over. 之后,您真的要在所有计算结束之前覆盖旧数组。 For static situations (no new pixels die/live), it is ok because new and old array are expected to be the same, for the others cases you find the error.
对于静态情况(没有新像素消亡/存活),这是可以的,因为新旧阵列应该是相同的,对于其他情况,您会发现错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.