- Overview
- executable, Eclipse and Maven projects
- executable, Eclipse and Maven projects
- executable, Eclipse and Maven projectsm
- executable, Eclipse and Maven projects
- executable, Eclipse and Maven projects
- executable, Eclipse and Maven projects
The universe of the Game of Life is a two-dimensional grid of cells, each of which is in one of two possible states, alive or dead. Every cell interacts with its eight neighbours, which are the cells that are horicontally, vertically, or diagonally adjecent. At each step in time, the following transitions occur:
Using the JLayer framework, this game can be modelled in two steps.
Class LifeCell is used for coding the game
from a cell's point of view and class LifeUniverse adds the global dynamics.
The code of the LifeCell class models the functionality of a single cell.
This is where the annotations of the JLayer framework come into play,
with the effect that a class Layer_LifeCell_ is generated
that can be used to wrap a two-dimensional array of type LifeCell[][]
creating the core of the LifeUniverse.
@LayerUnitpublic class LifeCell {@LayerFieldpublic int state;@LayerFieldLifeCell[] vector;@LayerMethodpublic void initState(Random r) { state = r.nextInt(2); } private int next;@LayerMethodpublic void nextState(){ int sum = 0; for (int i = 0; i < vector.length; i++) { sum += vector[i].state; } if (sum < 2 || sum > 3) { next = 0; } else if (sum == 3) { next = 1; } else { next = state; } }@LayerMethodpublic void updateState() { state = next; } }
Obviously, the field state represents the
two possible states of a cell (alive = 1 or dead = 0),
the one-dimensional array vector is used to link its eight neigbours
and method initState() is used to initialize the state.
The other items model the dynamic aspects.
Method nextState() implements the transition rules from above
and stores the next state in the local variable next, from where
method updateState() takes it to actually update the state of the cell.
The JLayer annotations direct the code generation performed by the annotation processor:
@LayerUnit indicates that this so called
unit class is to be processed by the JLayer annotation processor.
@LayerField marks those fields of a unit class
for which the dot notation is to be lifted to the array level.
@LayerMethod marks those methods of a unit class
for which the dot notation is to be lifted to the array level.
As mentioned above, from unit class LifeCell
the JLayer annotation processor automatically generates
the wrapper class Layer_LifeCell_,
which class LifeUniverse uses to model the dynamic aspects of the Game of Life.
The parts of the code that depend on the JLayer framework
are color coded.
public class LifeUniverse {
private LifeCell[][] lifeArray;
private Layer_LifeCell_ lifeLayer;
public void createNet(int width, int heigth) {
lifeArray = new LifeCell[width][heigth];
for(int i = 0; i < width; i++) {
for(int j = 0; j < heigth; j++) {
lifeArray[i][j] = new LifeCell();
}
}
lifeLayer = new Layer_LifeCell_(lifeArray);
lifeLayer.vector.connect(lifeLayer, IndexTools.isNeighbour);
}
public void initNet(int initSeed) {
Random r = new Random(initSeed);
lifeLayer.initState(r);
}
public void updateNet() {
lifeLayer.nextState();
lifeLayer.updateState();
}
}
The whole modelling is done by three methods and is
based on the two variables lifeArray
(a two-dimensional array with element type LifeCell)
and lifeLayer
(the wrapped array):
createNet() creates and initializes the array lifeArray,
wraps it and binds the result to variable lifeLayer.
After that, relation IndexTools.isNeighbour from the JLayer framework
can be used to link the vector layer lifeLayer.vector with the based layer
lifeLayer,
so that the interaction described in the introductory section can be performed;
initNet() randomly initializes the state of all cells;
updateNet() computes the next state of all cells
and then updates them.