【问题标题】:How i can draw a cellular automaton我如何绘制元胞自动机
【发布时间】:2019-10-08 15:23:14
【问题描述】:

我正在用java做一个元胞自动机练习,我遇到了一个问题。

CA 的逻辑部分工作正常,如果我希望它被安排在控制台上,它就准备好了,但我希望它被绘制在面板上,当它是 1 时绘制一个黑色方块,当它是 0 画一个白色方块

我们来解决问题

发生的事情是整个逻辑运行正常,但是在绘制java时只绘制最新一代的CA,我读到java paintComponent只在java决定时才起作用,而不是在调用它时。

我的问题是:如何最好地解决这个问题以及如何去做。

我想到了一些东西,但由于我对java不太了解,所以我决定问你

我想过可能将所有数组保存到一个然后从中绘制(但我不知道我该怎么做)我想也许每个循环都有一种绘制方法,但我没有找到它(我用repaint()但是没用)

无论如何,如果有人给我一个解决方案,我将不胜感激,我有这个问题好几天了,我还没有找到解决方案,下面是所有代码

import java.awt.BorderLayout;

import javax.swing.JFrame;    
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class CA extends JFrame {

    Rules rules = new Rules();

    public CA() {
        super("Cellular Automaton");
        setLayout(new BorderLayout());
        add(new GUI_CA(), BorderLayout.CENTER);
        pack();
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        setVisible(true);

    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                new CA();
            }   
        }); 
      }
    }
}
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Arrays;

import javax.swing.BorderFactory;
import javax.swing.JPanel;    

@SuppressWarnings("serial")
public class GUI_CA extends JPanel {

    int cellSize = 10;

    Rules rules = new Rules();

    private BufferedImage img;
    private Graphics2D g2d;

    public GUI_CA() {

        img =  new BufferedImage(cellSize, cellSize, BufferedImage.TYPE_INT_RGB);
        g2d = (Graphics2D) img.createGraphics();

        evolution();    
    }

    public void evolution() {
        rules.cells = new int[987/cellSize];
        rules.cells[rules.cells.length/2] = 1;
        System.out.println(Arrays.toString(rules.cells));
        for (int generationCount = 0; generationCount < 10; generationCount++) {
            rules.generate();
            System.out.println(Arrays.toString(rules.cells));
            repaint();
        }           
    }

    public void drawCA(Graphics g) {

        Graphics2D g2d = (Graphics2D) g;

        for (int i = 1; i < rules.cells.length -1; i++) {

            if (rules.cells[i] == 1) {
                g2d.setColor(Color.BLACK);
                g2d.fillRect(i * cellSize, rules.generation * 5, cellSize, cellSize);
                System.out.println(Arrays.toString(rules.cells));
            }else {
                g2d.setColor(Color.WHITE);
                g2d.fillRect(i * cellSize, rules.generation * 5, cellSize, cellSize);
            }
        }


    }

    public void drawBackground(Graphics g) {

        Graphics2D g2d = (Graphics2D) g;

        int width = 987;
        int height = 545;

        g2d.setPaint(Color.WHITE);
        g2d.fillRect(0, 0, width, height);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        drawBackground(g);
        drawCA(g);
        g.drawImage(img, 0, 0, null);

    }

    public Dimension getPreferredSize() {
        return new Dimension(987, 545);
    }

}
public class Rules {

    int[] cells;
    int[] ruleSet = new int[] {0, 1, 1, 1, 1, 0, 0, 0};
    //int cellSize = 10;
    int generation = 0;


    void generate() {

        int[] nextGeneration = new int[cells.length];

        for (int i = 1; i < cells.length - 1; i++) {

            int left = cells[i - 1];
            int me = cells[i];
            int right = cells [i + 1];

            nextGeneration[i] = rules(left, me, right);
        }
        cells = nextGeneration;
        generation++;

    }

    int rules(int left, int me, int right) {
        String s = "" + left + me + right;
        int index = Integer.parseInt(s, 2);
        //System.out.println(index);
        return ruleSet[index];      
    }
}

【问题讨论】:

  • Rules 似乎代表了CA的当前状态,对吧?对我来说,它只绘制最新的一代似乎是正确的。如果不是当前状态,你想画什么?
  • 您希望您的代码有何不同?
  • 另请参阅此版本的game of life 以获取提示。
  • 谢谢 Andrew Thompson,我去看看
  • 提示:添加@Code-Apprentice(或重要的@)以通知该人有新评论。

标签: java swing cellular-automata


【解决方案1】:

GUI 编程与控制台编程不同,因为您必须使用事件系统而不是仅使用 while 循环来重复生成输出的任务。我建议您首先添加一个按钮,用户单击该按钮可以进入下一代自动机。当您开始工作时,您可以更进一步添加一个计时器,该计时器会在一定时间后自动转到下一代。

【讨论】:

  • 感谢您的建议,这很有帮助。我一定会这样做的,谢谢。有没有办法让程序做所有的逻辑,然后把所有的世代画成一个整体?
  • @AndreDilay 你是什么意思“把所有的世代都画在一块”?您希望用户在屏幕上看到什么?
  • 我要画所有的世代,用户会看到最终的图案
  • CA 情况下的最终模式通常意味着最终代,而不是一次所有代。因为如果一个单元格一半时间是白色而另一半时间是黑色的,你会为最终模式做什么?把它画成灰色?或者有一个全黑/白屏幕?
  • 我想做这样的事情 [rule 30] (google.com/…) 并且用户会看到
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-25
相关资源
最近更新 更多