+++ /dev/null
-package eu.svjatoslav.sixth.e3d.examples.life;
-
-import eu.svjatoslav.sixth.e3d.geometry.Point3D;
-import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.base.AbstractCompositeShape;
-import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.base.SubShape;
-
-/**
- * This is our 2D game of life world. It contains 2D array of {@link Cell}'s.
- */
-class Matrix extends AbstractCompositeShape {
-
- /**
- * Empty space between cells.
- */
- private static final int BORDER = 5;
-
- /**
- * Matrix size X and Y. (Amount of cells.)
- */
- private static final int SIZE = 30;
-
- /**
- * Object marker in 3D scene. Allows to locate all stars from the scene.
- */
- private static final String GROUP_STARS = "stars";
-
- /**
- * Object marker in 3D scene. Allows to locate surface on the scene.
- */
- private static final String GROUP_SURFACE = "surface";
-
- /**
- * 2 dimensional matrix of cells
- */
- private final Cell[][] cells = new Cell[SIZE][];
-
- public Matrix(final Point3D location) {
- super(location);
-
-
- for (int x = 0; x < SIZE; x++) {
- cells[x] = new Cell[SIZE];
-
- // init Y row
- for (int z = 0; z < SIZE; z++) {
- // create cell and register it
- final Cell cell = new Cell(getCellLocation(x, z));
- cells[x][z] = cell;
- addShape(cell);
- }
- }
-
- setGroupForUngrouped(GROUP_SURFACE);
- }
-
- /**
- * Clear matrix.
- */
- public void clear() {
-
- // mark every cell as inactive
- for (int x = 0; x < SIZE; x++)
- for (int y = 0; y < SIZE; y++)
- cells[x][y].setActive(false);
-
- // remove history stars
- removeGroup(GROUP_STARS);
- }
-
- /**
- * Compute survived cells based on the rules of Conway's Game of Life.
- */
- private void computeSurvivedCells() {
-
- for (int y = 0; y < SIZE; y++)
- for (int x = 0; x < SIZE; x++)
- processCell(x, y);
-
- for (int y = 0; y < SIZE; y++)
- for (int x = 0; x < SIZE; x++)
- cells[x][y].setActive(cells[x][y].survives);
-
- }
-
- private void processCell(int x, int y) {
- int aliveNeighbours = countNeighbours(x, y);
-
- if (cells[x][y].isActive()) {
- cells[x][y].survives = ((aliveNeighbours == 2) || (aliveNeighbours == 3));
- } else {
- cells[x][y].survives = aliveNeighbours == 3;
- }
- }
-
- private int countNeighbours(int x, int y) {
- int result = 0;
- for (int ny = y - 1; ny <= y + 1; ny++)
- for (int nx = x - 1; nx <= x + 1; nx++)
- if (isCellAlive(nx, ny)) result++;
-
- if (isCellAlive(x, y)) result--;
-
- return result;
- }
-
- private boolean isCellAlive(int x, int y) {
- if (x < 0) return false;
- if (x >= SIZE) return false;
- if (y < 0) return false;
- if (y >= SIZE) return false;
- return cells[x][y].isActive();
- }
-
- /**
- * Evolve matrix for one iteration
- */
- public void evolve(final boolean preserveHistory) {
- if (preserveHistory)
- markActiveCells();
-
- shiftStarsUp();
-
- computeSurvivedCells();
- }
-
- private Point3D getCellLocation(final int x, final int z) {
- final int shift = -((SIZE / 2) * (Cell.SIZE + BORDER));
-
- return new Point3D(
- (x * (Cell.SIZE + BORDER)) + shift,
- 0,
- (z * (Cell.SIZE + BORDER)) + shift);
- }
-
- /**
- * Leave trail of active cells as stars above matrix.
- */
- private void markActiveCells() {
- // mark survived cells
- for (int x = 0; x < SIZE; x++)
- for (int y = 0; y < SIZE; y++)
- if (cells[x][y].isActive())
- addShape(new Star(getCellLocation(x, y)));
-
- setGroupForUngrouped(GROUP_STARS);
- }
-
- /**
- * Find all history tracking stars and shift them up.
- */
- private void shiftStarsUp() {
-
- for (final SubShape subShape : getGroup(GROUP_STARS))
- ((Star) subShape.getShape()).getLocation().translateY(-10);
- }
-}