- 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
.
@LayerUnit
public class LifeCell {@LayerField
public int state;@LayerField
LifeCell[] vector;@LayerMethod
public void initState(Random r) { state = r.nextInt(2); } private int next;@LayerMethod
public 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; } }@LayerMethod
public 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.