4

作为我自己的个人项目,我正在开发 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) {
  }
}
4

1 回答 1

15

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

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

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

人生游戏

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();
    }
}
于 2011-11-20T07:19:52.050 回答