class CubeState {
+ // Index of cube in glucose.model.cubes
public Integer index;
+ // Boolean which describes if cube is alive.
public boolean alive;
+ // List of this cubes neighbors
public List<Integer> neighbors;
public CubeState(Integer index, boolean alive, List<Integer> neighbors) {
}
}
-class Life extends SCPattern {
- public final int TIME_BETWEEN_RUNS = 100;
- public final int MAX_DEAD_BRIGHTNESS = 40;
- private final SinLFO xPos = new SinLFO(0, model.xMax, 5000);
- private final SinLFO yPos = new SinLFO(0, model.yMax, 5000);
+class L8onLife extends SCPattern {
+ // Controls the rate of life algorithm ticks, in milliseconds
+ private BasicParameter rateParameter = new BasicParameter("RATE", 122.5, 0.0, 2000.0);
+ // Controls if the cubes should be randomized even if something changes. Set above 0.5 to randomize cube aliveness.
+ private BasicParameter randomParameter = new BasicParameter("RAND", 0.0);
+ // Controls the brightness of dead cubes.
+ private BasicParameter deadParameter = new BasicParameter("DEAD", 25.0, 0.0, 100.0);
+ // Controls the saturation.
+ private BasicParameter saturationParameter = new BasicParameter("SAT", 90.0, 0.0, 100.0);
+
+ public final double MIN_ALIVE_PROBABILITY = 0.1;
+ public final double MAX_ALIVE_PROBABILITY = 0.8;
+
+ private final SinLFO xPos = new SinLFO(0, model.xMax, 3500);
- public List<CubeState> cube_states;
- public int time_since_last_run;
- public boolean any_changes_this_run;
+ // Contains the state of all cubes by index.
+ private List<CubeState> cube_states;
+ // Contains the amount of time since the last cycle of life.
+ private int time_since_last_run;
+ // Boolean describing if life changes were made during the current run.
+ private boolean any_changes_this_run;
- public Life(GLucose glucose) {
+ public L8onLife(GLucose glucose) {
super(glucose);
- outputCubeInfo();
+
+ //Print debug info about the cubes.
+ //outputCubeInfo();
+
initCubeStates();
time_since_last_run = 0;
any_changes_this_run = false;
+
+ addParameter(rateParameter);
+ addParameter(randomParameter);
+ addParameter(deadParameter);
+ addParameter(saturationParameter);
addModulator(xPos).trigger();
- addModulator(yPos).trigger();
}
public void run(double deltaMs) {
Integer i = 0;
- CubeState cube_state;
+ CubeState cube_state;
+ any_changes_this_run = false;
time_since_last_run += deltaMs;
- if(time_since_last_run < TIME_BETWEEN_RUNS) {
- return;
- }
- any_changes_this_run = false;
-
- for (Cube cube : model.cubes) {
- cube_state = this.cube_states.get(i);
+ for (Cube cube : model.cubes) {
+ cube_state = this.cube_states.get(i);
- if(shouldBeAlive(i)) {
+ if(shouldLightCube(cube_state)) {
lightLiveCube(cube);
} else {
lightDeadCube(cube);
- }
- i++;
+ }
+
+ i++;
}
- if(!any_changes_this_run) {
+ boolean should_randomize_anyway = (randomParameter.getValuef() > 0.5);
+ if(should_randomize_anyway || !any_changes_this_run) {
randomizeCubeStates();
}
- time_since_last_run = 0;
+ if(time_since_last_run >= rateParameter.getValuef()) {
+ time_since_last_run = 0;
+ }
}
+ public void lightLiveCube(Cube cube) {
+ for (LXPoint p : cube.points) {
+ float hv = max(0, lx.getBaseHuef() - abs(p.x - xPos.getValuef()));
+ colors[p.index] = lx.hsb(
+ hv,
+ saturationParameter.getValuef(),
+ 75
+ );
+ }
+ }
+
+ public void lightDeadCube(Cube cube) {
+ for (LXPoint p : cube.points) {
+ float hv = max(0, lx.getBaseHuef() - abs(p.x - xPos.getValuef()));
+ double dead_bright = deadParameter.getValuef() * Math.random();
+
+ colors[p.index] = lx.hsb(
+ hv,
+ saturationParameter.getValuef(),
+ dead_bright
+ );
+ }
+ }
+
public void outputCubeInfo() {
int i = 0;
for (Cube c : model.cubes) {
}
}
- private void randomizeCubeStates() {
- print("randomizing!\n");
-
- float f = (xPos.getValuef() / model.xMax) * 10;
- int mod_value = max(2, (int) f);
+ private void randomizeCubeStates() {
+ double prob_range = (1.0 - MIN_ALIVE_PROBABILITY) - (1.0 - MAX_ALIVE_PROBABILITY);
+ double prob = MIN_ALIVE_PROBABILITY + (prob_range * Math.random());
- for (CubeState cube_state: this.cube_states) {
- if( (cube_state.index % mod_value == 0) == cube_state.alive) {
- cube_state.alive = !cube_state.alive;
- }
+ //print("Randomizing cubes! p = " + prob + "\n");
+
+ for (CubeState cube_state: this.cube_states) {
+ cube_state.alive = (Math.random() <= prob);
}
}
Integer i = 0;
for (Cube c : model.cubes) {
- if(index == i) {
- i++;
- continue;
- }
-
- if(abs(c.x - cube.x) < (Cube.EDGE_WIDTH * 2) && abs(c.y - cube.y) < (Cube.EDGE_HEIGHT * 2)) {
- print("Cube " + i + " is a neighbor of " + index + "\n");
- neighbors.add(i);
+ if(index != i) {
+ if(abs(c.x - cube.x) < (Cube.EDGE_WIDTH * 2) && abs(c.y - cube.y) < (Cube.EDGE_HEIGHT * 2)) {
+ //print("Cube " + i + " is a neighbor of " + index + "\n");
+ neighbors.add(i);
+ }
}
i++;
return neighbors;
}
- public boolean shouldBeAlive(Integer index) {
- CubeState cube_state = this.cube_states.get(index);
- Integer alive_neighbor_count = countLiveNeighbors(cube_state);
-
+ public boolean shouldLightCube(CubeState cube_state) {
+ // Respect rate parameter.
+ if(time_since_last_run < rateParameter.getValuef()) {
+ any_changes_this_run = true;
+ return cube_state.alive;
+ } else {
+ return cycleOfLife(cube_state);
+ }
+ }
+
+ public boolean cycleOfLife(CubeState cube_state) {
+ Integer index = cube_state.index;
+ Integer alive_neighbor_count = countLiveNeighbors(cube_state);
boolean before_alive = cube_state.alive;
-
+
if(cube_state.alive) {
if(alive_neighbor_count < 2 || alive_neighbor_count > 3) {
cube_state.alive = false;
if(alive_neighbor_count == 3) {
cube_state.alive = true;
} else {
- cube_state.alive = false;
+ cube_state.alive = false;
}
}
this.cube_states.set(index, cube_state);
-
+
if(before_alive != cube_state.alive) {
- any_changes_this_run = true;
+ any_changes_this_run = true;
}
+
return cube_state.alive;
}
}
return count;
- }
-
- public void lightLiveCube(Cube cube) {
- for (LXPoint p : cube.points) {
- float hv = max(0, lx.getBaseHuef() - abs(p.x - xPos.getValuef()));
- float bv = max(0, 100 - abs(p.y - yPos.getValuef()));
- colors[p.index] = lx.hsb(
- hv,
- 100,
- //bv
- 75
- );
- }
- }
-
- public void lightDeadCube(Cube cube) {
- for (LXPoint p : cube.points) {
- float hv = max(0, lx.getBaseHuef() - abs(p.x - xPos.getValuef()));
- float bv = max(0, MAX_DEAD_BRIGHTNESS - abs(p.y - yPos.getValuef()));
-
- colors[p.index] = lx.hsb(
- hv,
- 100,
- //bv
- 10
- );
- }
- }
-
+ }
}