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