【问题标题】:Cellular Automaton Not Woorking [closed]元胞自动机不工作[关闭]
【发布时间】:2014-12-28 18:10:10
【问题描述】:

更新:只是为了指定,根据我如何更改规则,我可以设置它,以便在几代之内,所有细胞要么永久存活,要么死亡。我通过将语句回显到控制台来检查这一点。但是,这并没有反映在将所有单元格显示为始终相同颜色的 GUI 中。

我正在尝试实现一个简单的元胞自动机来复制生活游戏。这使用 MASON 库。我的三个班级:

Cell.java

package sim.app.gol;

import sim.engine.SimState;
import sim.engine.Steppable;
import sim.field.grid.IntGrid2D;
import sim.util.IntBag;

public class Cell implements Steppable {

    public IntGrid2D grid = new IntGrid2D(0,0);

    public void step(SimState state) {

        Matrix matrix = (Matrix) state;

        grid.setTo(matrix.matrix);

        for(int x = 0; x < grid.getWidth(); x++) {

            for(int y = 0; y < grid.getHeight(); y++) {

                IntBag nei = grid.getMooreNeighbors(x, y, 2, 0, false, new IntBag(), new IntBag(), new IntBag());

                int count = 0;

                for(int i = 0; i < nei.size(); i++) {

                    count += nei.get(i);

                }

                int currentState = grid.get(x, y);

                if(currentState == 0) {

                    if(count > 3)
                        matrix.matrix.set(x, y, 1);


                } else if(currentState == 1) {

                    matrix.matrix.set(x,y,0);


                }

            }


        }




    }

}

矩阵.java

package sim.app.gol;

import ec.util.MersenneTwisterFast;
import sim.engine.SimState;
import sim.field.grid.IntGrid2D;

public class Matrix extends SimState {

    public final int HEIGHT = 10;
    public final int WIDTH = 10;
    public IntGrid2D matrix = new IntGrid2D(HEIGHT, WIDTH);
    public final int NUM_CELLS = 80;

    public Matrix(long seed) {

        super(seed);

    }

    public void start() {

        super.start();

        // Utils for random number generator
        MersenneTwisterFast g = new MersenneTwisterFast();

        // We set everything to 0, no cells are active
        matrix.setTo(0);

        // Populating
        for(int i = 0; i < NUM_CELLS; i++) {

            int x = 0;
            int y = 0;

            // We don't want to mark as 'active' a cell that is already active
            do {
                x = g.nextInt(WIDTH);
                y = g.nextInt(HEIGHT);
            } while(matrix.get(x, y) == 1);

            matrix.set(x, y, 1);


        }

        schedule.scheduleRepeating(new Cell());


    }

    public static void main(String[] args) {


        doLoop(Matrix.class, args);
        System.exit(0);

    }



}

MatrixWithUI.java

package sim.app.gol;

import java.awt.Color;

import javax.swing.JFrame;

import sim.app.students.Students;
import sim.display.Console;
import sim.display.Controller;
import sim.display.Display2D;
import sim.display.GUIState;
import sim.engine.SimState;
import sim.portrayal.continuous.ContinuousPortrayal2D;
import sim.portrayal.grid.ObjectGridPortrayal2D;
import sim.portrayal.grid.ValueGridPortrayal2D;
import sim.portrayal.simple.OvalPortrayal2D;

public class MatrixWithUI extends GUIState {

    public Display2D display;
    public JFrame displayFrame;
    public ValueGridPortrayal2D matrixPortrayal = new ValueGridPortrayal2D();

    public static void main(String[] args) {

        MatrixWithUI mwu = new MatrixWithUI();
        Console c = new Console(mwu);
        c.setVisible(true);

    }

    public void start() {

        super.start();
        setupPortrayals();

    }

    public void load(SimState state) {

        super.load(state);
        setupPortrayals();

    }

    public void setupPortrayals() {

        Matrix matrix = (Matrix) state;
        matrixPortrayal.setField(matrix.matrix);
        matrixPortrayal.setPortrayalForAll(new OvalPortrayal2D());

        display.reset();
        display.setBackdrop(Color.white);

        display.repaint();

    }

    public void init(Controller c) {

        super.init(c);
        display = new Display2D(600,600,this);
        display.setClipping(true);

        displayFrame = display.createFrame();
        displayFrame.setTitle("Schoolyard Display");
        c.registerFrame(displayFrame);
        displayFrame.setVisible(true);
        display.attach(matrixPortrayal, "Yard");

    }

    public void quit() {

        super.quit();
        if (displayFrame != null) displayFrame.dispose();
        displayFrame = null;
        display = null;

    }

    public MatrixWithUI() { 

        super(new Matrix (System.currentTimeMillis())); 

    }

    public MatrixWithUI(SimState state) {

        super(state);

    }

    public static String getName() {

        return "Student Schoolyard Cliques";

    }

}

但是,由于某种原因,所有单元格都连续设置为 0(或关闭)。有什么想法吗?

【问题讨论】:

  • 我的建议是在调试器中单步调试代码和/或在关键点添加打印语句,看看到底哪里出了问题。
  • 你的规则不是康威的规则。它们似乎是导致整个矩阵在几代人左右内死亡的规则。是这样吗?
  • @NPE 就是这样,当我回显语句时,单元格会根据需要打开和关闭,但更改会反映在 GUI 中。但我不明白我哪里出了问题。
  • @max0005:最后一条评论应该就在您问题的开头。 :)
  • @NPE 呃抱歉,我会解决的:)

标签: java conways-game-of-life agent-based-modeling mason-abm


【解决方案1】:

注意:这是一个暂定答案,因为我目前无法验证。

首先,让我们看看documentation of ValueGridPortrayal2D。它说:

与其他FieldPortrayal2Ds 一样,此类使用底层SimplePortrayal2D 来绘制网格中的每个单独元素。提供了一个默认的SimplePortrayal2D 来绘制正方形。默认情况下,正方形的颜色是通过在用户提供的颜色表中查找正方形的值来确定的,或者如果没有,则通过在两种用户提供的颜色之间进行插值来确定。请参阅 setColorTable()setLevels() 方法。

因此,如果您选择正方形而不是椭圆形,则可以放弃这一行:

    matrixPortrayal.setPortrayalForAll(new OvalPortrayal2D());

相反,添加:

    java.awt.Color[] colorTable = new java.awt.Color[2];
    colorTable[0] = new java.awt.Color(1.0F,0.0F,0.0F,0.0F);
    colorTable[1] = new java.awt.Color(1.0F,0.0F,0.0F,1.0F);
    matrixPortrayal.setMap( new SimpleColorMap(colorTable) );

这应该为0 提供白色方块(在白色背景上透明),为1 提供红色方块。

如果您想绘制椭圆,使用地图的SimplePortrayal2D 的默认实现不可用。文档进一步说:

您还可以提供自己的自定义SimplePortrayal2D(使用setPortrayalForAll(...))来绘制您认为合适的元素,而不是矩形。你的SimplePortrayal2D 应该期望传递给它的draw 方法的对象是MutableDouble 类型。

所以我们需要重写 draw() 方法并将传递的对象 - 单元格值 - 视为 MutableDouble(我假设它们是指来自 @​​987654339@ 的对象):

    matrixPortrayal.setPortrayalForAll(new OvalPortrayal2D() {
        public void draw(Object object, Graphics2D graphics, DrawInfo2D info) {
            MutableDouble valueObj = (MutableDouble)object;
            if ( valueObj.intValue() == 0 ) {
                paint = new java.awt.Color(1.0F,0.0F,0.0F,0.0F);
            } else {
                paint = new java.awt.Color(1.0F,0.0F,0.0F,1.0F);
            }
            filled = true;
            super.draw(object, graphics, info);
        }

    });

所以我们创建了OvalPortrayal2D 的匿名子类。它从AbstractShapePortrayal2D 继承字段paintfilledscale。因此,我们使用特定值所需的颜色覆盖paint(java.awt.Paintjava.awt.Color 扩展),并确保填充椭圆形。

【讨论】:

  • 嗨@RealSkeptic,谢谢。嗯,恐怕我没有用于 Color 的构造函数,需要四个双打,我已经将其更改为似乎可以工作的整数?另外,我得到的只是蓝色背景:\
  • 您使用的是哪个版本的 Java? Java 7 中肯定有一个四浮点构造函数。如果您使用四个int 构造函数,则应该使用255 而不是1.0
  • 我在 Eclipse 上有 JRE7,但在 colorTable[0] = new java.awt.Color(1.0,0.0,0.0,0.0) 上出现错误;告诉我构造函数是未定义的
  • 对不起,你是对的。由于它们是浮点数,它们应该是1.0F0.0F 而不是1.00.0。我编辑了答案。
  • 另外,我假设数组的第二个元素应该以 ( 而不是 [?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多