Проблема с игрой в жизнь

Я работаю над 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) {
  }
}

person bringel    schedule 20.11.2011    source источник
comment
Что вы имеете в виду, что правила выходят не так?   -  person cHao    schedule 20.11.2011
comment
Обзор кода предназначен исключительно для рабочего кода. Не стесняйтесь возвращать свой код на проверку кода, как только он работает, для предложений по стилю / производительности.   -  person Winston Ewert    schedule 20.11.2011
comment
Было бы проще, если бы вы сказали, как они получаются неправильными, и включили код, который вы использовали для вычисления соседей ячейки. Также нужно знать, оборачиваетесь ли вы вокруг или в бесконечном мире.   -  person Dave Newton    schedule 20.11.2011
comment
"Issue with Game of Life" Может быть, если бы вы не относились к жизни как к игре...?   -  person qwertymk    schedule 20.11.2011
comment
Укажите sscce, который указывает на описанную вами проблему.   -  person trashgod    schedule 20.11.2011
comment
Например, паттерны мигания и жабы никогда не стабилизируются. Единственные, которые, похоже, работают, это неподвижные шаблоны. Кто-нибудь знает, правильно ли я их реализовал?   -  person bringel    schedule 20.11.2011
comment
Кто-нибудь знает, правильно ли я их реализовал? Очевидно, нет, но точно скажет только SSCCE.   -  person Andrew Thompson    schedule 20.11.2011


Ответы (1)


Я подозреваю1, проблема с вашим кодом заключается в том, что он устанавливает ячейки как живые или мертвые, как только проверяются соседи. Это привело к сбою моих ранних вариантов этого кода. Это изменение состояния должно быть отложено до тех пор, пока не будет проверена вся сетка (биосфера).

Этот пример показывает типичное поведение Game of Life.

  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();
    }
}
person Andrew Thompson    schedule 20.11.2011