Ordinary instances constructed from the class have not the information of position such as a grid position itself, however, a relation between grid-address and instances will give a very wide application area.
As a matter of fact, we can use indexed instance as the symbol name for the construction, then can deploy instances on the grid points. With the combination of the instance and the position, we can expect wide usage of Object Oriented Programming (OOP). We can call that system as, Instance Indexed Object Oriented Programming (IIOOP).
To show the availability of this method, I picked Life-Game up for an example.
1. preparing the name list for cell-instance
From a definition of grid, we can obtain the grid positioned cell name for the instance such as, { cell[1,1], cell[1,2], ... cell[n, m]}.
xsize = 31;
ysize = 21;
grid = Table[{i, j}, {i, ysize}, {j, xsize}];
cellName = Apply[cell, grid, {2}];
dispCells = Table[0, {i, ysize}, {j, xsize}];
2. defining the cell class
Following class has the methods named set[], get[], neighbour[], and nextMode[]. You can find the resolving method of self position from the self name, and the procedure of accessing other cell instances resolved from the self position.
cellClass[name_] :=
Module[{status = 0, x, y, nbrList, nbrT, newCell},
set[name[x_]] ^:= status = x;
get[name] ^:= status;
neighbour[name] ^:= (
newCell = status;
{y, x} = List @@ name;
nbrList = {
cell[Mod[y - 1, ysize, 1], Mod[x - 1, xsize, 1]],
cell[Mod[y - 1, ysize, 1], x],
cell[Mod[y - 1, ysize, 1], Mod[x + 1, xsize, 1]],
cell[y, Mod[x - 1, xsize, 1]],
cell[y, Mod[x + 1, xsize, 1]],
cell[Mod[y + 1, ysize, 1], Mod[x - 1, xsize, 1]],
cell[Mod[y + 1, ysize, 1], x],
cell[Mod[y + 1, ysize, 1], Mod[x + 1, xsize, 1]]};
nbrT = Total[Map[get[#] &, nbrList]];
If[nbrT == 3, newCell = 1] /; status == 0;
If[Or[nbrT <= 1, nbrT >= 4], newCell = 0] /; status == 1;
);
nextMode[name] ^:= status = newCell;
]
3. constructing cell-instances
Map[cellClass, cellName, {2}];
4. preparing display area of Life Game
Dynamic[ArrayPlot[dispCells, Mesh -> True]]
5. some initial patterns
a. pattern brinker
Map[set[#[0]] &, cellName, {2}];
{set[cell[3, 3][1]], set[cell[3, 4][1]], set[cell[3, 5][1]]};
b. pattern glider
Map[set[#[0]] &, cellName, {2}];
{set[cell[13, 13][1]], set[cell[13, 14][1]], set[cell[13, 15][1]],
set[cell[14, 13][1]], set[cell[15, 14][1]]};
c. pattern random
Map[set[#[RandomInteger[]]] &, cellName, {2}];
6. execution of Life Game
Do[
{Map[neighbour[#] &, cellName, {2}];
Map[nextMode[#] &, cellName, {2}];
dispCells = Map[get[#] &, cellName, {2}]},
200]
The usage of address as a symbol for the instance name is a curious way, however, is a strong method and can apply to multi core parallel computaition, through dividing the computational target area defined by grid. Enjoy!