Bild oben: Das Programm ermöglicht den Wechsel der Farben von Spielfeld und Life-Objekten während des Spielverlaufs. Außerdem kann eine Farbe ausgewählt werden, in welcher ein Objekt eine Spur hinter sich herzieht, so dass die Bewegung von Objekten verfolgt werden kann. Die Ablaufgeschwindigkeit ist einstellbar und Objekte können auch vom Anwender per Maus ins Spielfeld gezeichnet werden.
Game of Life
Der unten stehende Programmcode kann mittels Copy und Paste direkt in den leeren, geöffneten Processing Editor kopiert werden und sollte zumindest unter Windows 7 direkt nach dem Start funktionieren.
Achtung: Das Verzeichnis, in welchem sich die Datei des Processing Quellcodes befindet (Dateiname.pde) muss den gleichen Namen wie die Quellcode-Datei besitzen.
Die grafische Benutzeroberfläche ist nicht Bestandteil von Processing und wurde sozusagen "zu Fuß" programmiert. Der betreffende Code ist im folgenden Listing enthalten. Erfahrene Programmierer können ihn problemlos zur Erzeugung eigener grafischer Oberflächen zweckentfremden. Hinweise zu den Eigenschaften des Programms und seiner Bedienung finden Sie unter dem folgenden Link:
Hier nun zunächst der Code. Er wird später noch durch weitere Kommentare ergänzt.
//Life, 2015 may 15th / Programmer: Kurt Diedrich
// Arrays and Variables ##########################################################################
int[][] life = new int[450][300];
int[][] life2 = new int[450][300];
//basic values
int buttonflag;
int n;
int m;
int q;
int colorcntr;
int rot; int gruen; int blau;
int rot2; int gruen2; int blau2;
int rot3; int gruen3; int blau3;
// fillrandom
float wert1;
float wert2;
int wert3;
int wert4;
// Calculation function
int state;
int nb1; int nb2; int nb3; int nb4; int nb5; int nb6; int nb7; int nb8;
int summe;
int track=-1;
int flag1;
int delayzeit = 50;
// ####################################################################################
void setup()
{
size(1180,630); // Background
fill(50,60,70);
rect(0,0,1180,630);
fill(60,70,78);
rect(0,0,900,600); // Graphic display
// Create Buttons
fill(100,120,140);
rect(950,20,80,22);
rect(950,50,80,22);
rect(950,80,80,22);
rect(950,110,80,22);
rect(950,140,80,22);
rect(950,170,80,22);
rect(950,230,80,22); // Delay keys
rect(1080,230,80,22);
fill(255);
rect(1032,230,46,22); // Delay-Values Display
fill(0,80,0);
rect(1050,140,22,22); // LED for Tracking
// Button Text
fill(255);
smooth();
text("Fill Random", 960,36);
text("Play", 976,66);
text("Pause", 974,96);
text("Reset", 974,126);
text("Leave tracks", 957,156);
text("End", 980,186);
text("< Delay", 970,246);
text("Delay >", 1100,246);
fill(0);
text("50 ms", 1036, 246);
// color menue
for(n=0;n<=2;n++)
{
for (m=0;m<=4;m++)
{
if (colorcntr==0) {fill(67,78,84);}
if (colorcntr==1) {fill(129, 130, 141);}
if (colorcntr==2) {fill(56, 67, 103);}
if (colorcntr==3) {fill(81, 96, 149);}
if (colorcntr==4) {fill(8, 98, 128);}
if (colorcntr==5) {fill(60, 70, 78);}
if (colorcntr==6) {fill(135, 138, 146);}
if (colorcntr==7) {fill(59, 74, 109);}
if (colorcntr==8) {fill(89, 99, 155);}
if (colorcntr==9) {fill(16, 106, 135);}
if (colorcntr==10) {fill(255, 55, 5);}
if (colorcntr==11) {fill(251, 240, 67);}
if (colorcntr==12) {fill(5, 149, 255);}
if (colorcntr==13) {fill(20, 40, 180);}
if (colorcntr==14) {fill(0, 255, 0);}
rect(950+ m * 30, 270+n*30, 25,25);
colorcntr=colorcntr+1;
}
}
colorcntr=0;
// Color Presetting ############################################################
// Tracks
rot3 = 75;
gruen3 = 78;
blau3 = 100;
fill(rot3,gruen3, blau3);
rect(915, 270, 12,25);
// Background
rot = 60;
gruen = 70;
blau = 78;
fill(rot,gruen, blau);
rect(915, 300, 12,25);
// Cells
rot2 = 251;
gruen2 = 240;
blau2 = 67;
fill(rot2,gruen2, blau2);
rect(915, 330, 12,25);
fill(255);
text("Track", 1100,286);
text("Background", 1100,316);
text("Cells", 1100,346);
}
// End setup function #################################################################
void mouseReleased()
{
buttonflag=0;
}
void draw()
{
// Identify clicked buttons
if(mousePressed)
{
if ((mouseX>950) & (mouseX<1030) & (mouseY>20) & (mouseY<42)) {fillrandom();} // Fill Random
if ((mouseX>950) & (mouseX<1030) & (mouseY>50) & (mouseY<72)) { flag1=1; } // Play
if ((mouseX>950) & (mouseX<1030) & (mouseY>80) & (mouseY<102)) { flag1=0; } // Pause
if ((mouseX>950) & (mouseX<1030) & (mouseY>110) & (mouseY<132)) {reset();} // Reset
if ((mouseX>950) & (mouseX<1030) & (mouseY>140) & (mouseY<162)) // Leave Track
{
if ((track==1) & (buttonflag==0)) {fill(0,80,0); rect(1050,140,22,22); buttonflag=1;track=-track;}
if ((track== -1) & (buttonflag==0)) {fill(0,255,0); rect(1050,140,22,22); buttonflag=1;track=-track;}
}
if ((mouseX>950) & (mouseX<1030) & (mouseY>170) & (mouseY<192)) {exit();} // Exit
if ((mouseX>950) & (mouseX<1030) & (mouseY>230) & (mouseY<253)) // Delaytime -
{
delayzeit=delayzeit-1; if (delayzeit <0) {delayzeit=0;}
noStroke(); fill(255); rect(1034,232,44,20);
fill(0); text(delayzeit + " ms", 1036,246);
}
if ((mouseX>1080) & (mouseX<1160) & (mouseY>230) & (mouseY<253)) // Delaytime +
{
delayzeit=delayzeit+1; if (delayzeit >999) {delayzeit=999;}
noStroke(); fill(255); rect(1034,232,44,20);
fill(0); text(delayzeit + " ms", 1036,246);
}
// Colors
if ((mouseX>950) & (mouseX<975) & (mouseY>270) & (mouseY<295))
{rot3 = 67; gruen3 = 78; blau3 = 84; fill(rot3,gruen3, blau3); rect(915, 270, 12,25);}
if ((mouseX>980) & (mouseX<1005) & (mouseY>270) & (mouseY<295))
{rot3 = 129; gruen3 = 130; blau3 = 141; fill(rot3,gruen3, blau3); rect(915, 270, 12,25);}
if ((mouseX>1010) & (mouseX<1035) & (mouseY>270) & (mouseY<295))
{rot3 = 56; gruen3 = 67; blau3 = 103; fill(rot3,gruen3, blau3); rect(915, 270, 12,25);}
if ((mouseX>1040) & (mouseX<1065) & (mouseY>270) & (mouseY<295))
{rot3 = 81; gruen3 = 96; blau3 = 149; fill(rot3,gruen3, blau3); rect(915, 270, 12,25);}
if ((mouseX>1070) & (mouseX<1095) & (mouseY>270) & (mouseY<295))
{rot3 = 8; gruen3 = 98; blau3 = 128; fill(rot3,gruen3, blau3); rect(915, 270, 12,25);}
if (flag1==0) // Change background only in pause state
{
if ((mouseX>950) & (mouseX<975) & (mouseY>300) & (mouseY<325))
{rot = 60; gruen = 70; blau = 78; fill(rot,gruen, blau); rect(915, 300, 12,25);reset();}
if ((mouseX>980) & (mouseX<1005) & (mouseY>300) & (mouseY<325))
{rot = 135; gruen = 138; blau = 146; fill(rot,gruen, blau); rect(915, 300, 12,25);reset();}
if ((mouseX>1010) & (mouseX<1035) & (mouseY>300) & (mouseY<325))
{rot = 59; gruen = 74; blau = 109; fill(rot,gruen, blau); rect(915, 300, 12,25);reset();}
if ((mouseX>1040) & (mouseX<1065) & (mouseY>300) & (mouseY<325))
{rot = 89; gruen = 99; blau = 155; fill(rot,gruen, blau); rect(915, 300, 12,25);reset();}
if ((mouseX>1070) & (mouseX<1095) & (mouseY>300) & (mouseY<325))
{rot = 16; gruen = 99; blau = 135; fill(rot,gruen, blau); rect(915, 300, 12,25);reset();}
}
if ((mouseX>950) & (mouseX<975) & (mouseY>330) & (mouseY<355))
{rot2 = 255; gruen2 = 55; blau2 = 5; fill(rot2,gruen2, blau2); rect(915, 330, 12,25);}
if ((mouseX>980) & (mouseX<1005) & (mouseY>330) & (mouseY<355))
{rot2 = 251; gruen2 = 240; blau2 = 67; fill(rot2,gruen2, blau2); rect(915, 330, 12,25);}
if ((mouseX>1010) & (mouseX<1035) & (mouseY>330) & (mouseY<355))
{rot2 = 5; gruen2 = 149; blau2 = 255; fill(rot2,gruen2, blau2); rect(915, 330, 12,25);}
if ((mouseX>1040) & (mouseX<1065) & (mouseY>330) & (mouseY<355))
{rot2 = 20; gruen2 = 40; blau2 = 180; fill(rot2,gruen2, blau2); rect(915, 330, 12,25);}
if ((mouseX>1070) & (mouseX<1095) & (mouseY>330) & (mouseY<355))
{rot2 = 0; gruen2 = 255; blau2 = 0; fill(rot2,gruen2, blau2); rect(915, 330, 12,25);}
if((mouseX<900) & (mouseY < 600)) // Draw by mouse
{
fill(rot2, gruen2, blau2);
noStroke(); rect(mouseX,mouseY,2,2);
life[int(mouseX/2)][int(mouseY/2)]=1;
}
}
if(flag1==1) {play();}
}
// ########################################################################## Fill Array with cells
void fillrandom()
{
if (buttonflag==0)
{
noStroke();
fill(rot, gruen, blau);
rect(0,0,908,608);
for(n=0;n<=20000;n++)
{
wert1 = random(450);
wert2 = random(300);
wert3=int(wert1); wert4=int(wert2);
life[wert3][wert4] = 1;
}
// Display Random-Values
fill(rot2, gruen2, blau2);
for(m=2;m<=297;m++)
{
for(n=2;n<=447;n++)
{if(life[n][m]==1) {rect(2*n,2*m,2,2);}}
}
buttonflag=1;
}
}
// ###################################################################################### Play
void play()
{
//Scanning environment
for (m=1; m<=298;m++)
{
for (n=1; n<=449;n++)
{
state = life[n] [m];
nb1 = life[n][m - 1];
if (n > 1) {nb2 = life[n - 1][ m - 1];}
if (n == 1) {nb2 = life[448][ m - 1];}
if (n > 1) {nb3 = life[n - 1][m];}
if (n == 1) {nb3 = life[448][m];}
if (n > 1) {nb4 = life[n - 1][ m + 1];}
if (n == 1) {nb4 = life[448][m+1];}
nb5 = life[n][ m + 1];
if (n < 448) {nb6 = life[n + 1][ m + 1];}
if (n == 448) {nb6 = life[1][ m + 1];}
if (n < 448) {nb7 = life[n + 1][m];}
if (n == 448) {nb7 = life[1][m];}
if (n < 448) {nb8 = life[n + 1][m-1];}
if (n == 448) {nb8 = life[1][m-1];}
summe = nb1 + nb2 + nb3 + nb4 + nb5 + nb6 + nb7 + nb8;
if (state == 0)
{
if (summe == 3)
{
life2[n][ m] = 1;
}
}
if (state == 1)
{
if ((summe < 2) || (summe > 3))
{
life2[n][m]= 0;
}
if ((summe == 2) || (summe == 3))
{
life2[n][ m] = 1;
}
}
}
}
delay(delayzeit);
for (m=2; m<=297;m++)
{
for (n=2; n<=448;n++)
{
if (life2[n][ m] != life[n][m])
{
if (life2[n][ m] == 1)
{
fill(rot2, gruen2, blau2);
rect(2 * n, 2 * m, 2, 2);
}
if (life2[n][ m] == 0)
{
if (track == -1 )
{
fill(rot, gruen, blau);
rect(2 * n, 2 * m, 2, 2);
}
if (track == 1 )
{
fill(rot3, gruen3, blau3);
rect(2 * n, 2 * m, 2, 2);
}
}
}
}
}
for (m=1; m<=298;m++)
{
for (n=1; n<=449;n++)
{
life[n][ m] = life2[n] [m];
}
}
}
// ######################################################################################## Reset
void reset()
{
if (buttonflag==0)
{
flag1=0;
fill(rot, gruen, blau);
rect(0,0,908,608); // Graphic display
noStroke();
fill(rot2, gruen2, blau2);
for(m=0;m<=299;m++)
{
for(n=0;n<=449;n++)
{life[n][m]=0; life2[n][m]=0;}
}
buttonflag=1;
}
}