我试图创建conway的java游戏。我的代码没有问题,但随着游戏的输出。 The still lifes pattern按预期工作,但所有移动的结构都以不同的方式结束。
例如:1是活细胞; 0是死细胞
在维基页面上有一个振荡器,即闪光灯。就我而言,它的行为如下:
我正在applet中做所有的事情,我将其添加到jframe中。 这是applet代码(忽略德语注释,除非你是德语: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
}
}
答案 0 :(得分:3)
这是一个复杂的算法,因此我无法确保它在此之后可以正常工作,但其余代码看起来还不错。
boolean[][] newCells = cells.clone();
好的,clone()执行一个适用于基元的阴影副本。但是它不适用于二维数组(它作为ondimensional数组的ondimensional数组)。所以,你还有一个浅色的副本。
执行此操作后,在所有计算结束之前,您实际上是在覆盖旧数组。对于静态情况(没有新的像素死/实时),这是可以的,因为新旧数组应该是相同的,对于其他情况你会发现错误。