2 ^ 512 szabály
Térjünk vissza az 1-es szomszédsághoz, de most a dimenziók számát növeljük meg eggyel!
Ekkor egy sejtet 8 másik vesz körbe + maga a sejt: 9 elem
Két állapot sejtenként: 0 vagy 1
=> 2^9 = 512 esetre kell megadnunk, hogy a következő generációban a vizsgált sejt helyén 0-s vagy 1-es legyen, így esetenként megint 2-2 opciónk van.
(2^9)^2 = 2^512 =
134078079299425970995740249982058461274793
658205923933777235614437217640300735469768
018742981669034276900318581864860508537538
82811946569946433649006084096

Mostmár végképp elszállt a szabályok száma, már mondhatni lehetetlen felfogni a lehetőségek terét.
A Processing képes 3D-s alakzatokat is megjeleníteni, azonban az egyszerűség kedvéért most kényelmesebb lesz mozgó képet készíteni a szimulációból.
Így 2 tér(x,y) + 1 idő(képkockák) dimenziót kapunk:
import java.util.Random;
final int cellCount = 400;
int[][] cells; // a cellák 0 vagy 1 értékkel
boolean[] RULE;
float side;
Random rand = new Random();
void setup() {
size(1000,1000, P2D); // Ablak mérete, legyen négyzet
// Inicializásió
cells = new int[cellCount][cellCount];
side = 1.0 * width / cellCount;
RULE = new boolean[512];
generateNewRuleAndInitialise();
// A képernyő kitöltése
drawCells();
}
void generateNewRuleAndInitialise() {
println("\nNew RULES");
for (int i = 0; i < 512; i++) {
RULE[i] = rand.nextBoolean();
print(RULE[i] + " ");
}
RULE[511] = RULE[0]; // epilepszia gátló, kikommentelni csak saját felelősségre :)
println();
for (int i = 0; i < cellCount; i++) {
for (int j = 0; j < cellCount; j++) {
cells[i][j] = 0;
}
}
cells[cellCount/2][cellCount/2] = 1; // Egy aktív cella középen
}
void iterate() { // A következő generáció, a szélek fixek, csupa nulláknak vesszük őket.
int[][] cells2 = new int[cellCount][cellCount];
for (int i = 1; i < cellCount-1; i++) {
for (int j = 1; j < cellCount-1; j++) {
// Szomszédsági szabály
int value = 0;
int multiplyer = 0;
for (int y = -1; y < 2; y++) {
for (int x = -1; x < 2; x++) {
value += cells[i + y][j + x] << multiplyer;
multiplyer++;
}
}
// Értékadás a szábály alapján
if (RULE[value])
cells2[i][j] = 1;
else
cells2[i][j] = 0;
}
}
for (int i = 0; i < cellCount; i++) {
for (int j = 0; j < cellCount; j++) {
cells[i][j] = cells2[i][j];
}
}
}
void drawCells() { // Felrajzol egy generációt
noStroke();
for (int i = 0; i < cellCount; i++) {
for (int j = 0; j < cellCount; j++) {
if (cells[i][j] == 1) fill(0);
else fill(255);
rect(j * side, side * i, side, side);
}
}
}
void draw() {
iterate();
drawCells();
//delay(1);
}
void keyPressed() {
if (key == 'r' || key == 'R') {
generateNewRuleAndInitialise();
}
}
Az 512 esetre 512 boolean értékkel adok meg egy szabályt.
A szélső cellákat fixnek veszem a fenti kódban. Ennek némely szabály esetén a szélekről a középpont felé haladó zaj lesz az eredménye. Egy másik opció lenne, hogy összekötöm az ellentétes oldalon lévő cellákat egy tóruszt alkotva.
A program ténylegesen csak 2^511-en szabály tud megjeleníteni a következő sor és ok miatt:
RULE[511] = RULE[0];
A RULE[0] a csupa nullás állapotért, a RULE[511] pedig a csupes 1-es állapotért felelős, ha ez a kettő logikai érték nem egyezik, akkor minden iterációban gyorsan és zavaróan váltakozó fekete és fehér részek lesznek. Érthető okokból ezt lehet nem kéne engedélyezni.