细胞自动机不工作

时间:2014-12-28 18:10:11

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

更新:只是要指定,根据我如何更改规则,我可以设置它,所以在几代内所有单元格永久存活或死亡。我通过回显语句到控制台检查了这一点。但是,这并没有反映在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);


                }

            }


        }




    }

}

Matrix.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(或关闭)。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

注意:这是一个试探性的答案,因为我目前无法对其进行验证。

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

  

与其他FieldPortrayal2D一样,此类使用基础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(我假设它们是org.apache.commons.lang中的那个):< / p>

    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的匿名子类。它继承了paint中的字段filledscaleAbstractShapePortrayal2D。因此,我们使用特定值所需的颜色覆盖绘制(java.awt.Paintjava.awt.Color扩展),并确保填充椭圆。

相关问题