1 package org.woehlke.computer.kurzweil.cyclic.cellular.automaton.model;
2
3 import org.woehlke.computer.kurzweil.cyclic.cellular.automaton.config.ObjectRegistry;
4
5 import java.awt.*;
6 import java.io.Serializable;
7 import java.util.Date;
8 import java.util.Random;
9
10 import static org.woehlke.computer.kurzweil.cyclic.cellular.automaton.model.LatticeNeighbourhood.*;
11
12
13
14
15
16
17
18
19
20
21
22
23 public class CyclicCellularAutomatonLattice implements Serializable {
24
25 private static final long serialVersionUID = -594681595882016258L;
26
27 private Random random;
28
29 private volatile int[][][] lattice;
30 private volatile int source;
31 private volatile int target;
32
33 private final ObjectRegistry ctx;
34
35 private volatile LatticeNeighbourhood neighbourhood;
36
37 public CyclicCellularAutomatonLattice(ObjectRegistry ctx) {
38 this.ctx = ctx;
39 random = new Random(new Date().getTime());
40 startVonNeumann();
41 }
42
43 private void initCreateLattice() {
44 lattice = new int[2]
45 [(int) this.ctx.getConfig().getLatticeDimensions().getX()]
46 [(int) this.ctx.getConfig().getLatticeDimensions().getY()];
47 source = 0;
48 target = 1;
49 }
50
51 private void initFillLatticeByRandom() {
52 for (int y = 0; y < this.ctx.getConfig().getLatticeDimensions().getY(); y++) {
53 for (int x = 0; x < this.ctx.getConfig().getLatticeDimensions().getX(); x++) {
54 lattice[source][x][y] = random.nextInt(ctx.getColorScheme().getMaxState());
55 }
56 }
57 }
58
59 public synchronized void step() {
60
61 Point worldDimensions = this.ctx.getConfig().getLatticeDimensions();
62 for (int y = 0; y < worldDimensions.getY(); y++) {
63 for (int x = 0; x < worldDimensions.getX(); x++) {
64 lattice[target][x][y] = lattice[source][x][y];
65 int nextState = (lattice[source][x][y] + 1) % ctx.getColorScheme().getMaxState();
66 int west = (int) ((x - 1 + worldDimensions.getX()) % worldDimensions.getX());
67 int north = (int) ((y - 1 + worldDimensions.getY()) % worldDimensions.getY());
68 int east = (int) ((x + 1 + worldDimensions.getX()) % worldDimensions.getX());
69 int south = (int) ((y + 1 + worldDimensions.getY()) % worldDimensions.getY());
70 if (neighbourhood == MOORE_NEIGHBORHOOD || neighbourhood == WOEHLKE_NEIGHBORHOOD) {
71
72 if (nextState == lattice[source][west][north]) {
73 lattice[target][x][y] = nextState;
74 continue;
75 }
76
77 if (nextState == lattice[source][east][north]) {
78 lattice[target][x][y] = nextState;
79 continue;
80 }
81 if (neighbourhood == MOORE_NEIGHBORHOOD) {
82
83 if (nextState == lattice[source][east][south]) {
84 lattice[target][x][y] = nextState;
85 continue;
86 }
87 }
88
89 if (nextState == lattice[source][west][south]) {
90 lattice[target][x][y] = nextState;
91 continue;
92 }
93 }
94
95 if (nextState == lattice[source][x][north]
96 ) {
97 lattice[target][x][y] = nextState;
98 continue;
99 }
100
101 if (nextState == lattice[source][east][y]) {
102 lattice[target][x][y] = nextState;
103 continue;
104 }
105 if (neighbourhood == MOORE_NEIGHBORHOOD || neighbourhood == VON_NEUMANN_NEIGHBORHOOD) {
106
107 if (nextState == lattice[source][x][south]) {
108 lattice[target][x][y] = nextState;
109 continue;
110 }
111 }
112
113 if (nextState == lattice[source][west][y]) {
114 lattice[target][x][y] = nextState;
115 }
116 }
117 }
118 this.source = (this.source + 1) % 2;
119 this.target = (this.target + 1) % 2;
120 }
121
122 public int getCellStatusFor(int x, int y) {
123 return this.lattice[source][x][y];
124 }
125
126 public synchronized void startVonNeumann() {
127 initCreateLattice();
128 initFillLatticeByRandom();
129 this.neighbourhood = VON_NEUMANN_NEIGHBORHOOD;
130 }
131
132 public synchronized void startMoore() {
133 initCreateLattice();
134 initFillLatticeByRandom();
135 this.neighbourhood = MOORE_NEIGHBORHOOD;
136 }
137
138 public synchronized void startWoehlke() {
139 initCreateLattice();
140 initFillLatticeByRandom();
141 this.neighbourhood = WOEHLKE_NEIGHBORHOOD;
142 }
143 }