031a083595a4df60ee1a8997aa9930d393d3d880
[SugarCubes.git] / L8onWallace.pde
1 class CubeState {
2 public Integer index;
3 public boolean alive;
4 public List<Integer> neighbors;
5
6 public CubeState(Integer index, boolean alive, List<Integer> neighbors) {
7 this.index = index;
8 this.alive = alive;
9 this.neighbors = neighbors;
10 }
11 }
12
13 class Life extends SCPattern {
14 public final int TIME_BETWEEN_RUNS = 100;
15 public final int MAX_DEAD_BRIGHTNESS = 40;
16 private final SinLFO xPos = new SinLFO(0, model.xMax, 5000);
17 private final SinLFO yPos = new SinLFO(0, model.yMax, 5000);
18
19 public List<CubeState> cube_states;
20 public int time_since_last_run;
21 public boolean any_changes_this_run;
22
23 public Life(GLucose glucose) {
24 super(glucose);
25 outputCubeInfo();
26 initCubeStates();
27 time_since_last_run = 0;
28 any_changes_this_run = false;
29 addModulator(xPos).trigger();
30 addModulator(yPos).trigger();
31 }
32
33 public void run(double deltaMs) {
34 Integer i = 0;
35 CubeState cube_state;
36
37 time_since_last_run += deltaMs;
38
39 if(time_since_last_run < TIME_BETWEEN_RUNS) {
40 return;
41 }
42 any_changes_this_run = false;
43
44 for (Cube cube : model.cubes) {
45 cube_state = this.cube_states.get(i);
46
47 if(shouldBeAlive(i)) {
48 lightLiveCube(cube);
49 } else {
50 lightDeadCube(cube);
51 }
52 i++;
53 }
54
55 if(!any_changes_this_run) {
56 randomizeCubeStates();
57 }
58
59 time_since_last_run = 0;
60 }
61
62 public void outputCubeInfo() {
63 int i = 0;
64 for (Cube c : model.cubes) {
65 print("Cube " + i + ": " + c.x + "," + c.y + "," + c.z + "\n");
66 ++i;
67 }
68 print("Edgeheight: " + Cube.EDGE_HEIGHT + "\n");
69 print("Edgewidth: " + Cube.EDGE_WIDTH + "\n");
70 print("Channelwidth: " + Cube.CHANNEL_WIDTH + "\n");
71 }
72
73 private void initCubeStates() {
74 List<Integer> neighbors;
75 boolean alive = false;
76 CubeState cube_state;
77 this.cube_states = new LinkedList<CubeState>();
78 Integer i = 0;
79
80 for (Cube c : model.cubes) {
81 neighbors = findCubeNeighbors(c, i);
82 alive = true;
83 cube_state = new CubeState(i, alive, neighbors);
84 this.cube_states.add(cube_state);
85 ++i;
86 }
87 }
88
89 private void randomizeCubeStates() {
90 print("randomizing!\n");
91
92 float f = (xPos.getValuef() / model.xMax) * 10;
93 int mod_value = max(2, (int) f);
94
95 for (CubeState cube_state: this.cube_states) {
96 if( (cube_state.index % mod_value == 0) == cube_state.alive) {
97 cube_state.alive = !cube_state.alive;
98 }
99 }
100 }
101
102 public List<Integer> findCubeNeighbors(Cube cube, Integer index) {
103 List<Integer> neighbors = new LinkedList<Integer>();
104 Integer i = 0;
105
106 for (Cube c : model.cubes) {
107 if(index == i) {
108 i++;
109 continue;
110 }
111
112 if(abs(c.x - cube.x) < (Cube.EDGE_WIDTH * 2) && abs(c.y - cube.y) < (Cube.EDGE_HEIGHT * 2)) {
113 print("Cube " + i + " is a neighbor of " + index + "\n");
114 neighbors.add(i);
115 }
116
117 i++;
118 }
119
120 return neighbors;
121 }
122
123 public boolean shouldBeAlive(Integer index) {
124 CubeState cube_state = this.cube_states.get(index);
125 Integer alive_neighbor_count = countLiveNeighbors(cube_state);
126
127 boolean before_alive = cube_state.alive;
128
129 if(cube_state.alive) {
130 if(alive_neighbor_count < 2 || alive_neighbor_count > 3) {
131 cube_state.alive = false;
132 } else {
133 cube_state.alive = true;
134 }
135
136 } else {
137 if(alive_neighbor_count == 3) {
138 cube_state.alive = true;
139 } else {
140 cube_state.alive = false;
141 }
142 }
143
144 this.cube_states.set(index, cube_state);
145
146 if(before_alive != cube_state.alive) {
147 any_changes_this_run = true;
148 }
149 return cube_state.alive;
150 }
151
152 public Integer countLiveNeighbors(CubeState cube_state) {
153 Integer count = 0;
154 CubeState neighbor_cube_state;
155
156 for(Integer neighbor_index: cube_state.neighbors) {
157 neighbor_cube_state = this.cube_states.get(neighbor_index);
158 if(neighbor_cube_state.alive) {
159 count++;
160 }
161 }
162
163 return count;
164 }
165
166 public void lightLiveCube(Cube cube) {
167 for (LXPoint p : cube.points) {
168 float hv = max(0, lx.getBaseHuef() - abs(p.x - xPos.getValuef()));
169 float bv = max(0, 100 - abs(p.y - yPos.getValuef()));
170 colors[p.index] = lx.hsb(
171 hv,
172 100,
173 //bv
174 75
175 );
176 }
177 }
178
179 public void lightDeadCube(Cube cube) {
180 for (LXPoint p : cube.points) {
181 float hv = max(0, lx.getBaseHuef() - abs(p.x - xPos.getValuef()));
182 float bv = max(0, MAX_DEAD_BRIGHTNESS - abs(p.y - yPos.getValuef()));
183
184 colors[p.index] = lx.hsb(
185 hv,
186 100,
187 //bv
188 10
189 );
190 }
191 }
192
193 }