Building the simulation model

First, we set up the Model as root domain containing all cells. It is derived from BasicDomain as base class of all domains. Remember, domains help you to structure your model and may contain other domains or agents. In this case we only have one root level domain containing all agents.

package org.simplesim.examples.gameoflife;

import org.simplesim.model.BasicDomain;

public class Model extends BasicDomain {

	private final Cell world[][];
	private final int width, height;

	public Model(int w, int h) {
		width=w;
		height=h;
		world=new Cell[width][height];
	}
	
	public void createCells(double lifeProbability) {
		for (int y=0; y<height; y++) for (int x=0; x<width; x++) {
			final Cell cell=new Cell(x,y,false);
			cell.getState().setAlive(Math.random()<lifeProbability);
			world[x][y]=cell;
			cell.addToDomain(this);
		}
	}
	
	public void connectCells() {
		for (int y=0; y<height; y++) for (int x=0; x<width; x++) {
			int left, right, up, down;
			if (x==0) left=width-1; else left=x-1;
			if (x==(width-1)) right=0; else right=x+1;
			if (y==0) down=height-1; else down=y-1;
			if (y==(height-1)) up=0; else up=y+1;
			// connect cell outport with inport of neighbor - clockwise
			final Cell cell=getCell(x,y);
			cell.getOutport().connect(getCell(x,up).getInport());
			cell.getOutport().connect(getCell(right,up).getInport());
			cell.getOutport().connect(getCell(right,y).getInport());
			cell.getOutport().connect(getCell(right,down).getInport());
			cell.getOutport().connect(getCell(x,down).getInport());
			cell.getOutport().connect(getCell(left,down).getInport());
			cell.getOutport().connect(getCell(left,y).getInport());
			cell.getOutport().connect(getCell(left,up).getInport());
		}
	}

	public Cell getCell(int x, int y) { return world[x][y]; }

	public String getName() {	return "world"; }

}

In the constructor, we set up the grid of cells as an array. The method createCells adds the cells to the domain. Note that registering elements to the domain by addToDomain is crucial to ensure the simulation’s functionality.

After that, the method connectCells calculates the position of all neighboring cells. We also construct a wrap around of the grid. Then we connect each cell to its eight neighbors. This is done by simply using the connectTo method of the outport with the other cell’s inport. Ports can be connected this way similar to an extension cord. Please note that connections are directed, they forward messages just in one direction. To send and receive messages, an agent needs at least two ports.

Finally, we have to orchestrate the model building and start the simulation run. That’s what we’re taking a look at in the next step.