更新:只是要指定,根据我如何更改规则,我可以设置它,所以在几代内所有单元格永久存活或死亡。我通过回显语句到控制台检查了这一点。但是,这并没有反映在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(或关闭)。有什么想法吗?
答案 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
中的字段filled
,scale
和AbstractShapePortrayal2D
。因此,我们使用特定值所需的颜色覆盖绘制(java.awt.Paint
,java.awt.Color
扩展),并确保填充椭圆。