-1

Обновление: Просто, чтобы указать, в зависимости от того, как я изменяю правила, я могу установить его так, чтобы в течение нескольких поколений все ячейки были либо живыми, либо мертвыми. Я проверил это, повторив инструкции на консоль. ОДНАКО, это не отражается в графическом интерфейсе, который показывает все ячейки как всегда одного цвета.Cellular Automaton Not Woorking

Я пытаюсь реализовать простой сотовый автомат, чтобы воспроизвести игру жизни. Это использует библиотеку 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

Мое предложение состояло в том, чтобы выполнить код в отладчике и/или добавить заявления печати в стратегических точках, чтобы увидеть, где именно происходит что-то не так. – NPE

+0

Ваши правила не являются правилами Конвей. Они, похоже, являются правилами, которые приведут всю матрицу к смерти в течение нескольких поколений или около того. Это то, что происходит? – RealSkeptic

+0

@NPE это то, когда я повторяю ячейки ячеек, которые включаются и выключаются по мере необходимости, но изменения отражаются в графическом интерфейсе. Но я не могу понять, где я ошибся. – MrD

ответ

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 должен ожидать, что объекты, переданные его методу рисования, будут иметь тип MutableDouble.

Так что нам нужно переопределить метод draw() и обработать переданный объект - значение ячейки - как MutableDouble (с помощью которого я предполагаю, что они означают одно из org.apache.commons.lang):

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) с цветом, который нам нужен для определенного значения, и убедитесь, что овал заполнен.

+0

Привет @RealSkeptic, спасибо. Хм, боюсь, у меня нет конструктора для цвета, берущего четыре двойника, я изменил его на ints, который, похоже, работает? Кроме того, все, что я получаю, это синий фон: \ – MrD

+0

Какую версию Java вы используете? Конечно, есть конструктор с четырьмя платами в Java 7. Если вы используете четыре конструктора 'int', вы должны использовать' 255' вместо '1.0'. – RealSkeptic

+0

У меня есть JRE7 на Eclipse, но получаю сообщение об ошибке colorTable [0] = new java.awt.Color (1.0,0.0,0.0,0.0); говоря, что конструктор не определен – MrD

Смежные вопросы