ARTIFICIAL LIFE
Conwayova hra života – školní projekt (Java applet)
ČVUT FEL, 2001
Zadání:
Uvažujme jednobuněčné organismy, které sídlí v políčkách šachovnice n x n. Vyjděme z pevně zvoleného rozmístění buněk na šachovnici. Vzhled kolonie buněk v bezprostředně následujícím okamžiku je jednoznačně určen jasnými pravidly, která řídí, zdrod a přežití buněk. J.H. Conway navrhl pracovat s pravidly, která se týkají pouze 8 přímých sousedů buňky na šachovnici:
- ZROD BUŇKY - v okolí prázdného políčka jsou právě 3 buňky,
- PŘEŽITÍ - v okolí buňky jsou 2 nebo 3 buňky,
- UHYNUTÍ - v okolí buňky je 0, 1,4,5,6, 7 nebo 8 buněk.
Simulujte vývoj populace jednobuněčných organismů v čase. Pokuste se nalézt zajímavé tvary výchozí populace - například stabilizovaný obrazec (který se v průběhu životního cyklu populace nemění), pulzující obrazec, atd. (program)
Program:
Zhodnocení:
Zajímavé funkční struktury jsem hledal náhodným generováním výchozí matice. Při zacela náhodném rozložení docházelo často k tomu, že kolonie poměrně rychle vymřela již při prvním kroku.
To se mi podařilo kompenzovat náhodným generováním ne jednotlivých buněk, ale vždy sady buněk.
V dalším vývojovém kroku jsem jednotlivým buňkám v sadě (tj. v submatici 3x3) přiřadil váhy. Při zvažování zda buňka přežije či ne, jsem použil poměr 5:1 na přežití.
V tomto provedení prgram funguje v současnosti.
Poměrně velkou roli na vývoj kolonie hraje i nastavení poměru "oživovaných" buněk ku celkovému počtu pozic v matici. Údaj je možno změnit pomocí tlačítek "<" a ">". Hodnota odopovídá %-počtu celkem generovaných buněk ku celkovému počtu pozic matice.
Nejzajímavějších výsledků jsem dosáhl v oblasti 10-20%.
(program)
Výpis programu:
import java.lang.*;
import java.awt.*;
import java.awt.Graphics;
import java.applet.Applet;
import java.awt.event.*;
public class ALcell extends Applet implements ActionListener {
Button nextbutton, loadbutton,bplus,bminus;
TextField textload,textload2,textload3;
public ALcell() {
nextbutton = new Button("Next generation");
loadbutton = new Button("Initialize");
textload = new TextField("130",3);
textload2 = new TextField("80",3);
bminus = new Button("<");
textload3 = new TextField("20",3);
bplus = new Button(">");
nextbutton.addActionListener(this);
loadbutton.addActionListener(this);
textload.addActionListener(this);
bminus.addActionListener(this);
textload2.addActionListener(this);
bplus.addActionListener(this);
textload3.addActionListener(this);
add(nextbutton, "South");add(textload, "South");add(textload2, "South");add(bminus, "South");add(textload3, "South");add(bplus, "South");add(loadbutton, "South");
textload.setEnabled(false);
textload2.setEnabled(false);
textload3.setEnabled(false);
}
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if(e.getSource()==nextbutton) {
nextbutton.setEnabled(false);
bsimulate=true;
init();
nextbutton.setEnabled(true);
}
if(e.getSource()==bminus) {if (percell>2) percell=percell-2;textload3.setText(String.valueOf(percell));}
if(e.getSource()==bplus) {if (percell<78) percell=percell+2;textload3.setText(String.valueOf(percell));}
if(e.getSource()==loadbutton) {
loadbutton.setEnabled(false);
String sx=textload.getText();
String sy=textload2.getText();
String sp=textload3.getText();
bmcr=false;
init();
loadbutton.setEnabled(true);
}
}
int frxsize=700;
int frysize=500;
int xm=130+2;
int ym=80+2;
int percell=20;
byte[][] matrix=new byte[xm][ym];
boolean bmcr=false;
boolean bsimulate=false;
public void init() {
int x;
int y;
//jen kdyz neni init
if (!bmcr){
for (x = 0; x < xm; x++){for(y=0;y<ym;y++){matrix[x][y]=0;}}
for (int i = 0; i < ((int)(xm*ym*percell/100/9)); i++) {
int xrnd=(int)(2+((xm-4)*Math.random())); int yrnd=(int)(2+((ym-4)*Math.random()));
for (int py = -1; py<=1; py++){for (int px = -1; px<=1; px++){if ((3*Math.random())>0.5) matrix[xrnd+px][yrnd+py]=(byte)32;}}
}
}
if (bmcr){
// test na sousedy
for (x=1; x < (xm-2); x++){for(y=1;y<(ym-2);y++){
if (matrix[x-1][y]>=(byte)32) {matrix[x][y]++;};
if (matrix[x+1][y]>=(byte)32) {matrix[x][y]++;};
if (matrix[x][y-1]>=(byte)32) {matrix[x][y]++;};
if (matrix[x][y+1]>=(byte)32) {matrix[x][y]++;};
if (matrix[x-1][y-1]>=(byte)32) {matrix[x][y]++;};
if (matrix[x-1][y+1]>=(byte)32) {matrix[x][y]++;};
if (matrix[x+1][y-1]>=(byte)32) {matrix[x][y]++;};
if (matrix[x+1][y-1]>=(byte)32) {matrix[x][y]++;};
};};
//nevim jak je v Jave log.op. OR takze to vypada trochu hodne hrozne
for (x = 1; x < (xm-2); x++){for(y=1;y<(ym-2);y++){
if (matrix[x][y]>=(byte)32) {
if (matrix[x][y]==(byte)(32+0)) {matrix[x][y]=(byte)0;};
if (matrix[x][y]==(byte)(32+1)) {matrix[x][y]=(byte)0;};
if (matrix[x][y]==(byte)(32+2)) {matrix[x][y]=(byte)32;};
if (matrix[x][y]==(byte)(32+3)) {matrix[x][y]=(byte)32;};
if (matrix[x][y]==(byte)(32+4)) {matrix[x][y]=(byte)0;};
if (matrix[x][y]==(byte)(32+5)) {matrix[x][y]=(byte)0;};
if (matrix[x][y]==(byte)(32+6)) {matrix[x][y]=(byte)0;};
if (matrix[x][y]==(byte)(32+7)) {matrix[x][y]=(byte)0;};
if (matrix[x][y]==(byte)(32+8)) {matrix[x][y]=(byte)0;};
} else {if (matrix[x][y]==(byte)3){matrix[x][y]=(byte)(32);}
else {matrix[x][y]=(byte)(0);};};
}} //end for x,y
bmcr=true;
repaint();
// } //ends while bsimulate do
}
public void start(){}
public void run() {}
// Zobrazeni vystupu v appletu
public void paint(Graphics g) {
if ((xm*ym)<5e4){
if (bmcr) {
g.drawString("Applet Simulates Conways Life. KUI 2000/2001",400,(frysize-40));
for (int y = 1; y < (ym-2); y++) { for (int x = 1; x < (xm-2); x++) {
//if (matrix[x][y]==(byte)0) {g.drawString(".",(15+x*5),(40+y*5));};
if (matrix[x][y]==(byte)32) {g.drawString("°",(15+x*5),(40+y*5));};
};}
};
}
//pokud je vice jak 5e4 bunek tak nevykresluj
else {
int c=0;
for (int y = 2; y < (ym-4); y++) { for (int x = 2; x < (xm-4); x++) {
if (matrix[x][y]>=32) {c++;};
}}
System.out.println(" total alive > "+c);
};
}
public static void main(String args[]) {
ALcell ma = new ALcell();
Frame f = new Frame("-A-L-");
f.add(ma, "Center");
f.setSize(700,500);
ma.init();
ma.start();
f.setVisible(true);
}
public String getAppletInfo() {
return "Applet Simulates Conways Life. mailto:[email protected]";}
}
(program)