簡體   English   中英

康威的生活游戲無法按預期進行

[英]conway's game of life doesn't work as expected

我試圖在Java中創建conway的現場游戲。 我的代碼沒有問題,但游戲的輸出卻沒有問題。 靜物模式按預期工作,但是所有移動的結構都以不同的方式結束。

例如: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

        }
}

這是一個復雜的算法,所以我不能保證在此之后它會起作用,但是其余的代碼看起來還可以。

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

好的,clone()執行一個卷影副本,該卷影副本非常適合基元。 但是它不適用於二維數組 (充當一維數組的一維數組)。 因此,您的副本仍然很淺。

之后,您真的要在所有計算結束之前覆蓋舊數組。 對於靜態情況(沒有新像素消亡/存活),這是可以的,因為新舊陣列應該是相同的,對於其他情況,您會發現錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM