java - 康威的生命游戏没有按预期进行

标签 java conways-game-of-life

我试图用java创建康威的现场游戏。我的代码没有问题,但游戏的输出没有问题。 The still lifes pattern按预期工作,但所有移动结构都会以不同的方式结束。

例如:1是活细胞; 0 是一个死细胞

维基页面上有一个振荡器,即信号灯。就我而言,它的行为如下:

game of life problem

我正在一个小程序中完成所有操作,并将其添加到 jframe 中。 这是小程序代码(忽略德语注释,除非您是德国人: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

        }
}

最佳答案

这是一个复杂的算法,因此我无法向您保证它在此之后能够正常工作,但其余代码看起来没问题。

boolean[][] newCells = cells.clone();

好的,clone() 执行的卷影复制非常适合基元。但它不适用于二维数组(它充当一维数组的一维数组)。所以,你仍然有一个浅拷贝。

这样做之后,您实际上是在所有计算结束之前覆盖旧数组。对于静态情况(没有新像素死/活),这是可以的,因为新旧数组应该是相同的,对于其他情况,您会发现错误。

关于java - 康威的生命游戏没有按预期进行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12061154/

相关文章:

Java 枚举行为

java - javac 能否推断出将 x.getClass() 和 x 一起使用的正确泛型?

python - 康威的生命游戏没有正确计算邻居数量

java - 生活游戏规则无法正常运行

python - 康威的生命游戏 : check if a cell is in the corner/border

java - 有人可以告诉我为什么我的生命游戏代码不起作用吗?

Javascript 未定义函数错误

java - 如何将 GUI 添加到此 java 程序中?

java - Spark-java:过滤器之前的路径排除

java - 在 Apache Tapestry 页面访问上传的文件