生命游戏的问题

时间:2011-11-20 03:53:29

标签: java swing conways-game-of-life

我正在努力将Conway的生活游戏的Java实现作为我自己的个人项目。到目前为止它的确有效,但规则出错了。预期的模式并没有像它应该的那样出现。我的代码有问题吗?

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Cell extends JComponent implements MouseListener {

  private int row, col;
  private boolean isLiving;

  public Cell(int r, int c) {
    this.row = r;
    this.col = c;
    this.addMouseListener(this);
  }

  public void isAlive(int neighbors) {
    if (this.isLiving) {
      if (neighbors < 2) {
        this.isLiving = false;
      } else if (neighbors == 2 || neighbors == 3) {
        this.isLiving = true;
      } else if (neighbors > 3) {
        this.isLiving = false;
      }
    } else {
      if (neighbors == 3) {
        this.isLiving = true;
      }
    }
  }

  public boolean isLiving() {
    return this.isLiving;
  }

  public void paintComponent(Graphics g) {
    if (this.isLiving) {
      g.fillRect(0, 0, 10, 10);
    } else {
      g.drawRect(0, 0, 10, 10);
    }
  }

  public void mouseClicked(MouseEvent e) {
    this.isLiving = !this.isLiving;
  }

  public void mouseEntered(MouseEvent e) {
  }

  public void mouseExited(MouseEvent e) {
  }

  public void mousePressed(MouseEvent e) {
  }

  public void mouseReleased(MouseEvent e) {
  }
}

1 个答案:

答案 0 :(得分:14)

怀疑 1 您的代码的问题在于,一旦检查邻居,它就会将单元格设置为生存或死亡。这导致我的此代码的早期变体失败。必须延迟这种状态变化,直到检查整个网格(生物圈)。

此示例显示了典型的生命游戏行为。

  1. 请注意,“怀疑不是答案”,因此最好发布SSCCE。
  2. Game of Life

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.util.Random;
    
    public class GameOfLife extends JPanel {
    
        private final int row, col;
        private boolean isLiving;
    
        public static Random random = new Random();
    
        public GameOfLife(int r, int c) {
            this.row = r;
            this.col = c;
            MouseListener listener = new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    isLiving = !isLiving;
                    repaint();
                }
            };
            this.addMouseListener(listener);
            isLiving = random.nextBoolean();
        }
    
        public boolean isAlive(int neighbors) {
            boolean alive = false;
            if (this.isLiving) {
                if (neighbors < 2) {
                    alive = false;
                } else if (neighbors == 2 || neighbors == 3) {
                    alive = true;
                } else if (neighbors > 3) {
                    alive = false;
                }
            } else {
                if (neighbors == 3) {
                    alive = true;
                }
            }
            return alive;
        }
    
        public void setAlive(boolean alive) {
            isLiving = alive;
        }
    
        public boolean isLiving() {
            return this.isLiving;
        }
    
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (this.isLiving) {
                g.fillRect(0, 0, getWidth() - 1, getHeight() - 1);
            } else {
                g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
            }
        }
    
        public static void main(String[] args) {
            final int s = 40;
            final GameOfLife[][] biosphere = new GameOfLife[s][s];
            final JPanel gui = new JPanel(new GridLayout(s, s, 2, 2));
            for (int ii = 0; ii < s; ii++) {
                for (int jj = 0; jj < s; jj++) {
                    GameOfLife cell = new GameOfLife(ii, jj);
                    cell.setPreferredSize(new Dimension(10, 10));
                    gui.add(cell);
                    biosphere[ii][jj] = cell;
                }
            }
    
            ActionListener al = (ActionEvent ae) -> {
                boolean[][] living = new boolean[s][s];
                for (int ii = 0; ii < s; ii++) {
                    for (int jj = 0; jj < s; jj++) {
                        int top = (jj > 0 ? jj - 1 : s - 1);
                        int btm = (jj < s - 1 ? jj + 1 : 0);
                        int lft = (ii > 0 ? ii - 1 : s - 1);
                        int rgt = (ii < s - 1 ? ii + 1 : 0);
                        int neighbors = 0;
                        if (biosphere[ii][top].isLiving()) {
                            neighbors++;
                        }
                        if (biosphere[ii][btm].isLiving()) {
                            neighbors++;
                        }
                        if (biosphere[lft][top].isLiving()) {
                            neighbors++;
                        }
                        if (biosphere[lft][btm].isLiving()) {
                            neighbors++;
                        }
                        if (biosphere[lft][jj].isLiving()) {
                            neighbors++;
                        }
                        if (biosphere[rgt][jj].isLiving()) {
                            neighbors++;
                        }
                        if (biosphere[rgt][top].isLiving()) {
                            neighbors++;
                        }
                        if (biosphere[rgt][btm].isLiving()) {
                            neighbors++;
                        }
                        living[ii][jj] = biosphere[ii][jj].isAlive(neighbors);
                    }
                }
                for (int ii = 0; ii < s; ii++) {
                    for (int jj = 0; jj < s; jj++) {
                        biosphere[ii][jj].setAlive(living[ii][jj]);
                    }
                }
                gui.repaint();
            };
    
            Timer timer = new Timer(50, al);
            timer.start();
    
            JOptionPane.showMessageDialog(null, gui);
            timer.stop();
        }
    }
    
相关问题