L8on's life
[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 = (i % 6 == 0);
83 // alive = true;
84 cube_state = new CubeState(i, alive, neighbors);
85 this.cube_states.add(cube_state);
86 ++i;
87 }
88 }
89
90 private void randomizeCubeStates() {
91 for (CubeState cube_state: this.cube_states) {
92 if( (cube_state.index % 2 == 0) == cube_state.alive) {
93 cube_state.alive = !cube_state.alive;
94 }
95 }
96 }
97
98 public List<Integer> findCubeNeighbors(Cube cube, Integer index) {
99 List<Integer> neighbors = new LinkedList<Integer>();
100 Integer i = 0;
101
102 for (Cube c : model.cubes) {
103 if(index == i) {
104 i++;
105 continue;
106 }
107
108 if(abs(c.x - cube.x) < (Cube.EDGE_WIDTH * 2) && abs(c.y - cube.y) < (Cube.EDGE_HEIGHT * 2)) {
109 neighbors.add(i);
110 }
111
112 i++;
113 }
114
115 return neighbors;
116 }
117
118 public boolean shouldBeAlive(Integer index) {
119 CubeState cube_state = this.cube_states.get(index);
120 Integer alive_neighbor_count = countLiveNeighbors(cube_state);
121
122 boolean before_alive = cube_state.alive;
123
124 if(cube_state.alive) {
125 if(alive_neighbor_count < 2 || alive_neighbor_count > 3) {
126 cube_state.alive = false;
127 } else {
128 cube_state.alive = true;
129 }
130
131 } else {
132 if(alive_neighbor_count == 3) {
133 cube_state.alive = true;
134 } else {
135 cube_state.alive = false;
136 }
137 }
138
139 this.cube_states.set(index, cube_state);
140
141 if(before_alive != cube_state.alive) {
142 any_changes_this_run = true;
143 }
144 return cube_state.alive;
145 }
146
147 public Integer countLiveNeighbors(CubeState cube_state) {
148 Integer count = 0;
149 CubeState neighbor_cube_state;
150
151 for(Integer neighbor_index: cube_state.neighbors) {
152 neighbor_cube_state = this.cube_states.get(neighbor_index);
153 if(neighbor_cube_state.alive) {
154 count++;
155 }
156 }
157
158 return count;
159 }
160
161 public void lightLiveCube(Cube cube) {
162 for (LXPoint p : cube.points) {
163 float hv = max(0, lx.getBaseHuef() - abs(p.x - xPos.getValuef()));
164 float bv = max(0, 100 - abs(p.y - yPos.getValuef()));
165 colors[p.index] = lx.hsb(
166 hv,
167 100,
168 //bv
169 75
170 );
171 }
172 }
173
174 public void lightDeadCube(Cube cube) {
175 for (LXPoint p : cube.points) {
176 float hv = max(0, lx.getBaseHuef() - abs(p.x - xPos.getValuef()));
177 float bv = max(0, MAX_DEAD_BRIGHTNESS - abs(p.y - yPos.getValuef()));
178
179 colors[p.index] = lx.hsb(
180 hv,
181 100,
182 //bv
183 10
184 );
185 }
186 }
187
188 }