0

我正在尝试创建 conway 的 Java 直播游戏。我的代码没有问题,但是游戏的输出。静物模式按预期工作,但所有移动的结构都以不同的方式结束。

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

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

人生问题游戏

我在一个小程序中做所有的事情,我添加到一个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

        }
}
4

1 回答 1

3

这是一个复杂的算法,所以我不能保证它会在这之后工作,但其余的代码看起来没问题。

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

好的,clone() 执行了一个适用于图元的卷影副本。但它不适用于二维数组(充当一维数组的一维数组)。所以,你还有一个浅拷贝。

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

于 2012-08-21T19:09:02.090 回答