Historia wymaga pasterzy, nie rzeźników.


● Dla każdej komórki bierze się pod uwagę komórki z jej ortogonalnego sąsiedztwa, oznacza to, że pod uwagę bierzemy czterech sąsiadów, na rysunku zaznaczonych zielonym kolorem.
rys. 1


● Jeśli suma wartości komórek na dole i na górze nie jest równa zero, wtedy stan branej pod uwagę komórki zmienia się zgodnie z modulo (resztą z dzielenia) sumy wartości komórek po prawej i lewej stronie przez wartości komórek na dole i na górze.

rys. 2
rys. 3

1
( 32 + 7
1 8) mod (81 + 7
1 8) = 1
5

(dla ułatwienia nie zmieniono wartości sąsiadów na rys. 3)

● Jeśli suma komórek na dole oraz na górze wynosi zero, wtedy należy brać pod uwagę jedynie sumę wartości komórek po lewej i prawej stronie i dodać ją do obecnego stanu komórki.
Uwaga: najwyższa wartość 255! W przypadku, gdy suma wyniesie więcej, stan zmienia się na 255.

rys. 4
rys.5

1
( 75 + 175) + 6
3 = 8
3 6
Przypadek, w którym bierzemy najwyższą możliwą wartość, 255


● Automat posiada trzy tryby, które zmienia się za pomocą klawiszy 1,2 i 3. Różnią się od siebie sposobem rozwoju.

● Kliknięcie LPM prowadzi do ponownej populacji w oknie













Tryb 1









Tryb 2









Tryb 3









KOD PROGRAMU

int W = 600; // szerokość okna (powinno być dzielne przez S) int H = 400; // wysokość okna (powinno być dzielne przez S) int S = 2; // rozmiar komórek w pikselach
int C = W / S; // ilość column w automacie
int R = H / S; // ilość wierszy w automacie
int mode=1; // która wersja jest wyświetlana na początku int [][] curr; // obecne pokolenie
int [][] prev; // poprzednie pokolenie
color [] palette; // 256 kolorów

void setup() {
size(W,H);
frameRate(15); // im więcej tym szybciej
background(0);
noStroke();
curr = new int[R][C];
prev = new int[R][C];
populate();
palette = new int[256];
for (int i=0; i<256; i++) {
int k = (int)(pow(i/256.0,2)*255.0); // intensywność wybranego koloru,(pow(x,y)=x^y) palette[i] = color(0,k,0); // kolor (R,G,B)
}
}

void populate() {
for (int r=0; r<R; r++) {
for (int c=0; c<C; c++) {

prev[r][c] = curr[r][c] = (int)random(10); // można zmieniać!
// (10) - mała populacja początkowa, w miarę szybko się rozwija
}
}
}


void update() {
for (int r=0; r<R; r++) {
for (int c=0; c<C; c++) {

int state = curr[r][c];

int lr = prev[r][(c-1+C)%C] + prev[r][(c+1)%C]; // modulo %

int tb = prev[(r-1+R)%R][c] + prev[(r+1)%R][c]; int breed = 0;

switch(mode) { // tryby


case 1 : breed = (state+lr)&0xff; break;
// aktywny


case 2 : breed = ((state+lr))&0xf; break;
// najbardziej “matrixowy” efekt, usuwa najwyższe wartości bitów, wolniejszy rozwój case 3 : breed = (state+100)&0xff; break;
// bardzo zaszumiony efekt

// itd

}

curr[r][c] = (tb==0) ? breed : (lr%tb)&0xff;
}
}
}

void render() {
for (int r=0,y=0; r<R; y+=S,r++) {
for (int c=0,x=0; c<C; x+=S,c++) {

fill(palette[curr[r][c]]);

rect(x,y,S,S); // kształt
}
}
}

void swap() {
int [][] temp = curr;
curr = prev;
prev = temp;
}

void ui() {
fill(255,42,0,120);
text("mode: " + mode, 5, H-5);
}

void draw() {
update();
render();
ui();
swap();
}

void keyPressed() {
if ((key>='1') && (key<='3'))
mode = key - '0';
}

void mousePressed() {
populate();
}






Podstrony