| Programmieraufgaben Hier wird regelmäßig eine neue Programmieraufgabe gestellt, die dann gelöst werden soll und in Zusammenarbeit mit den Moderatoren auch besprochen werden kann. |
Diskussion: [leicht bis mittel-schwer] Game Of Life im Forum Programmieraufgaben, in der Kategorie Code Kitchen; Wie kann es nur sein, dass der Klassiker vergessen wurde Eingereicht von Tarantoga Zitat: Die Aufgabe wäre es eine Anwendung ...
![]() |
| | #1 (permalink) | |
| Moderator ![]() Registriert seit: 20.07.05 ![]() ![]() ![]() ![]() ![]() Likes: 156 | Wie kann es nur sein, dass der Klassiker vergessen wurde Eingereicht von Tarantoga Zitat:
Es gibt ein Spielfeld, auf dem Zellen "leben". Nach einiger Zeit ist der Lebenszyklus der Zellen vorbei und die Zeit der nächsten Generation bricht an (simpel gesagt: nächste Runde). Dann wird die neue Zellgeneration so berechnet: - eine Zelle wird dann geboren, wenn sie genau drei lebende Nachbarn hat - eine Zelle stirbt, wenn sie weniger als 2 lebende Nachbarn hat - eine Zelle bleibt weiterhin am leben, wenn sie 2 oder 3 lebende Nachbarn hat - Zellen mit mehr als 3 lebenden Nachbarn sterben an Überbevölkerung Einfach: In der einfachsten Variante reicht es aus, ein Feld von einer vorgegebenen Maximalgröße zu haben und die Startgeneration im Code "fest" einzutragen. Als Ausgabe darf eine Konsole/Datei genommen werden. Fortgeschritten: Fortgeschrittene Variante soll ein (theoretisch) unendliches Spielfeld haben und die Startgeneration aus einer Textdatei einlesen. Das Format ist auf "benutzerfreundlichkeit" getrippt und arbeitet nur mit ASCIIs: Leerzeichen für "nichts" und "X" für eine Zelle: Code: X X
XXX
X Auch hier: Ausgabe über Konsole/Datei reicht aus, allerdings muss man sich überlegen, nicht das gesamte (unendliche) Spielfeld auszugeben, sondern nur den relevanten Ausschnitt mit den Zellen Der Ausschnitt darf aber eine feste Größe haben (also z.B 80x50 und ähnliches) und den nicht mehr "hineinpassenden" Teil des Feldes weglassen. Es geht hier eigentlich nur darum, nicht einfach stumpf die ersten x Position anzuzeigen (egal ob leer, oder mit Zellen gefüllt), sondern die Ausgabe "intelligent" auf die vorhanden Zellen zu "setzen" Beispielausgabe auf der Konsole (die als ASCII gespeichert auch als Eingabe für den Startzustand benutzt werden kann) Code: XX XX
XX XX
XX
X X
XX
XXX
X X
XX XXX
XX XX
X X XXX
X X XX X X
X XX XXX
XX XX
XX
XX X X
XX XX
XX
XX
XX X
XX XXXX XX XX XXX
XX XX XXX XX XXXX
X XX die "schwere" Variante hat zusätzlich zu allen Funktionen eine hübsche grafische Ausgabe (Applet/Fenster/WebSeite usw). Dabei sollte unbedingt bedacht werden, dass es auch so genannte "Glider" gibt: ![]() also "Objekte", die sich von der großen "Zellmasse" losmachen und auf "Reisen" gehen. Hierzu sollte man sich überlegen, wie man eine halbwegs benutzerfreundliche Anzeige umsetzt (das strickte Wegzoomen geht ja nur bis zur eine gewissen Grenze, das simple Scrollen auf dem Feld kann auch alles andere als einfach sein, wenn die Zellen zu weit auseinander liegen - also wird man sich zumindest eine Kombination überlegen müssen Zusätzlich kann man sich einige Gedanken zu seinem verwendeten Algorithmus machen - insbesondere für sehr große Felder. Auf Wunsch kann ich ein 500x500 Feld freigeben, bei dem man nach X Runden eine vordefinierte Ausgabe erhält und die Laufzeit sich sehr deutlich je nach verwendetem Algorithmus unterscheidet.
__________________ Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf! Selig, wer nichts zu sagen hat und trotzdem schweigt. | |
| | |
| | #2 (permalink) |
| Member of Honour ![]() Registriert seit: 02.10.01 ![]() Likes: 0 | Bei meiner Lösung handelt es sich um eine simple Demonstration mit Hilfe von SDL; in C programmiert. Das Einlesen aus einer Text-Datei macht für mich keinen Sinn, aber vlt. werde ich eine Zoom- und Zeichen-Funktion nach WM und Uni-Prüfungen nachliefern. ![]() Code: #include <stdlib.h>
#include <SDL.h>
#include <time.h>
#include "SDL_draw.h"
SDL_Surface *screen;
#define W 160
#define H 120
#define QU 5
#define PERC 90
int quads[W][H];
void init() {
int i,k;
for (i=0;i<W;i++) { for (k=0;k<H;k++) { if ((rand() % 100 + 1)>PERC) quads[i][k]=1; else quads[i][k]=0; } }
}
Uint32 update (Uint32 intervall, void *parameter) {
int i,k,sum,chk[20000][3],count=0;
for (i=0;i<W;i++) {
for (k=0;k<H;k++) {
sum=0;
if (i>0 && k>0 && quads[i-1][k-1]==1) sum++;
if (k>0 && quads[i][k-1]==1) sum++;
if (i<(W-1) && k>0 && quads[i+1][k-1]==1) sum++;
if (i>0 && k<(H-1) && quads[i-1][k+1]==1) sum++;
if (k<(H-1) && quads[i][k+1]==1) sum++;
if (i<(W-1) && k<(H-1) && quads[i+1][k+1]==1) sum++;
if (i>0 && quads[i-1][k]==1) sum++;
if (i<(W-1) && quads[i+1][k]==1) sum++;
if (quads[i][k]==0 && sum==3) {
chk[count][0]=i;
chk[count][1]=k;
chk[count][2]=1;
}
if (quads[i][k]==1 && (sum<2 || sum>3)) {
chk[count][0]=i;
chk[count][1]=k;
chk[count][2]=0;
}
count++;
}
}
for (i=0;i<count;i++) quads[chk[i][0]][chk[i][1]]=chk[i][2];
return 50;
}
void draw() {
int i,k;
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
for (i=0;i<W;i++) { for (k=0;k<H;k++) { if (quads[i][k]==1) Draw_FillRect(screen,i*QU,k*QU,QU,QU,SDL_MapRGB(screen->format,0,0,255)); } }
SDL_Flip(screen);
}
int main() {
Uint8 *check; SDL_TimerID timer; SDL_Event event; int quit=0;
srand(time(NULL));
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) == -1) {printf("Can't init SDL: %s\n", SDL_GetError());exit(1);}
atexit(SDL_Quit);
screen = SDL_SetVideoMode(W*QU, H*QU, 16,SDL_SWSURFACE | SDL_DOUBLEBUF );
if (screen == NULL) {printf("Can't set video mode: %s\n", SDL_GetError());exit(1);}
init();
timer = SDL_AddTimer (0, update, NULL);
while (!quit) {
SDL_PollEvent(&event);
check=SDL_GetKeyState(NULL);
if (check [SDLK_ESCAPE]) quit=1;
draw();
}
return 0;
} Geändert von Indi (09.07.10 um 23:05 Uhr) |
| | |
| HaBOT | |
| |
| | #3 (permalink) | |
| Moderator ![]() Registriert seit: 20.07.05 ![]() ![]() ![]() ![]() ![]() Likes: 156 | Zitat:
![]() Und Dir entgeht auch die sehr wichtige Erkenntniss, dass das "Indi" Muster sich zu einer großen Gemeinschaft entwickelt, sich stabilisiert und "Glider" bildet
__________________ Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf! Selig, wer nichts zu sagen hat und trotzdem schweigt. | |
| | |
| | #4 (permalink) |
| Member of Honour ![]() Registriert seit: 02.10.01 ![]() Likes: 0 | Stimmt, es muss sehr faszinierend sein, zu beobachten wie sich "Indi" weiterentwickelt. ^^ ![]() Aber wie gesagt, ich werde noch eine Zeichnen-Funktion einbauen, damit ich mit dem Mauszeiger auf dem Arbeitsblatt zeichnen kann. Deswegen meinte ich, dass das Einlesen aus einer Datei für mich aktuell keinen Sinn macht. |
| | |
| | #5 (permalink) |
| Member of Honour ![]() | das is ja was cooles, ich werd das auch mal versuchen umzusetzen
__________________ » Flattr mich! - Wenn dir mein Beitrag geholfen hat! « <| 2 AMD Opterons 2384@ 8x3,2ghz | Tyan S2915 | 10GB | 2x 8800GT | 8400GS | Dell 3008WFP + 2x2007FP |> |
| | |
| | #6 (permalink) |
| Registriert seit: 26.08.06 ![]() Likes: 0 | Habe Conway's Game of Life vor einiger Zeit mal geschrieben. Habe allerdings keine variable Feldgröße und die Startbelegung der Zellen ist bei mir im Quelltext festgelegt, werde mal gucken das ich diese Sachen noch mache. Habe aber als Spielefläche die Form eines Torus genommen, so kommen sich bewegende Gebilde wieder ins Spielfeld gelaufen. Code: #include <stdio.h>
#include<stdlib.h>
int zeile = 15;
int spalte = 30;
int zustand[15][30];
int tmp[15][30];
void initialisieren(){
for ( int i = 0; i < zeile; i++){
for (int j = 0; j < spalte ;j++){
zustand[i][j] = 0;
}
}
zustand[0][0] = 1;
zustand[0][1] = 1;
zustand[0][29] = 1;
zustand[1][0] = 1;
zustand[4][11] = 1;
zustand[5][10] = 1;
zustand[5][11] = 1;
zustand[5][12] = 1;
zustand[6][11] = 1;
zustand[14][0] = 1;
for ( int i = 0; i < zeile; i++){
for (int j = 0; j < spalte ;j++){
tmp[i][j] = 0;
}
}
}
void neuegeneration(){
for (int laufzeile = 0; laufzeile < zeile; laufzeile++){
for ( int laufspalte = 0; laufspalte < spalte; laufspalte++){
int zelllebend = 0;
for ( int zaehllaufzeile = laufzeile - 1; zaehllaufzeile < (laufzeile + 2); zaehllaufzeile++){
for ( int zaehllaufspalte = laufspalte - 1; zaehllaufspalte < (laufspalte + 2); zaehllaufspalte++){
zelllebend = zelllebend + zustand[(zaehllaufzeile + zeile) % zeile][(zaehllaufspalte + spalte) % spalte];
}
}
if (zustand[laufzeile][laufspalte] == 0 && zelllebend ==3){
tmp[laufzeile][laufspalte] = 1;
}
else{
if (zustand[laufzeile][laufspalte] == 1 && (zelllebend ==3 || zelllebend ==4)){
tmp[laufzeile][laufspalte] = 1;
}
else{
tmp[laufzeile][laufspalte] = 0;
}
}
}
}
}
void genuebertrag(){
for ( int i = 0; i < zeile; i++){
for (int j = 0; j < spalte ;j++){
zustand[i][j] = tmp[i][j];
}
}
}
void ausgabe(){
for ( int i = 0; i < zeile; i++){
for (int j = 0; j < spalte ;j++){
printf("%d", zustand[i][j]);
}
printf("\n");
}
printf("\n");
}
int main(){
system("cls");
initialisieren();
printf("Ausgangszustand:\n");
ausgabe();
for ( int i = 0; true; i++){
printf("%d.Iteration:\n", i+1);
neuegeneration();
genuebertrag();
ausgabe();
system("pause");
system("cls");
}
} |
| | |
| | #7 (permalink) |
| Moderator ![]() Registriert seit: 11.02.06 ![]() ![]() ![]() ![]() ![]() ![]() Likes: 195 | Hier ist schon einmal mein erster Lösungsansatz in Java, ich werde den aber noch überarbeiten und das einlesen von Textdateien für die Startkonfiguration (bis jetzt geht es nur manuell durch Mausklicks auf die Zellen) & einen Stop-Button hinzufügen (bis jetzt muss man zum beenden das Fenster schliessen), auch die Torus Form der Welt muss noch rein... Aber zuerst muss ich meinen WM-Kater auskurieren... ![]() Quellcode Geändert von Tarantoga (26.11.10 um 16:25 Uhr) |
| | |
| | #8 (permalink) | |
| Moderator ![]() Registriert seit: 11.02.06 ![]() ![]() ![]() ![]() ![]() ![]() Likes: 195 | Wie versprochen habe ich den Code noch einmal überarbeitet und folgende Änderungen vorgenommen: -der Anwendung wurde ein Pause-Button hinzugefügt, mit dem es jederzeit möglich ist die Simulation anzuhalten und z. B. Änderungen an der aktuellen Zellpopulation vorzunehmen -die Methode nachbarnZaehlen() wurde so verändert, dass Zellen am Rand die Zellen am gegenüberliegenden Rand als Nachbarn haben (Torus-Form). So wird eine unendliche Welt simuliert & ich spare mir den Zoom... ![]() Auf das einlesen von Textdateien habe ich vorerst doch verzichtet, da es mir wesentlich nutzerfreundlicher erscheint die Startpopulation mit der Maus einzustellen - vielleicht schreibe ich aber noch einmal einen Editor, der das Erstellen der Textdateien etwas komfortabler gestaltet... Ansonsten bin ich mit dem Code recht zufrieden, obwohl man ihn natürlich noch optimieren könnte - z. B. eine eigene Klasse für den MouseListener erstellen, die alle MouseEvents behandelt oder es wäre sicher auch eleganter anstatt den einfachen Timer zu benutzen, die Animation in einen eigenen Thread auszulagern... Zitat:
![]() Quellcode Geändert von Tarantoga (26.11.10 um 16:35 Uhr) | |
| | |
| | #9 (permalink) |
| Moderator ![]() Registriert seit: 20.07.05 ![]() ![]() ![]() ![]() ![]() Likes: 156 | Startzustand: Code: XX XX X Code: (0,-1), (1,-1),(-1,0), (0,0), (0,1) Als grober Orientierungswert: dauert bei mir auf dem Laptop (1.6 GHZ Core2Duo, "endless field" Umsetzung, SingleThread, alle Schritte ohne Animation) jeweils ~3 und ~5 Sekunden (innerhalb einer Python 2.6.5 Testsuit ).PS: bei den Outputs könnte es sich am Anfang und am Ende jeweils um eine Leerzeile handeln. Sonst ist der Output auf "minimale" Ausgabengröße zugeschnitten - d.h so groß, wie die "Randzellen" jeweils links/rechts/oben/unten verstreut sind.
__________________ Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf! Selig, wer nichts zu sagen hat und trotzdem schweigt. |
| | |
| | #10 (permalink) |
| Hallo, ich habe das einfache Schema mit den 4 Regeln mal in Ruby programmiert .. jedoch ist mir der Verlauf noch nicht ganz klar ... sei gegeben: _XXX _X_X ____ so meine Schleifen laufen nun durchs Array ... das erste X (oben links) hat 2 lebende Nachbarn, also passiert nichts ... nächstes X (darunter) das selbe ... nächstes X wäre das mittlere oben ... dieses X hat 4 lebende Nachbarn, würde also sterben. So jetzt meine Frage ... setze ich den neuen Zustand mitten im Durchlauf oder speichere ich den Zustand und ändere ihn erst, nachdem die Schleife komplett durchgelaufen ist? | |
| | |
| | #11 (permalink) | |
| Moderator ![]() Registriert seit: 20.07.05 ![]() ![]() ![]() ![]() ![]() Likes: 156 | Zitat:
Sollte dann so aussehen: Code: >>> print lifestring(step) X X X X X
__________________ Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf! Selig, wer nichts zu sagen hat und trotzdem schweigt. | |
| | |
| | #12 (permalink) |
| Alles klar, dann sollte das jetzt wohl passen: Code Steps etwas blöd mit Ruby, weil man die Console nicht löschen kann, wodurch man auch keine Animation hinbekommt Geändert von chumbalum (10.07.10 um 01:15 Uhr) | |
| | |
| | #13 (permalink) |
| Senior Member Registriert seit: 07.01.03 ![]() Likes: 13 | Einfach permanent ausgeben und den User das Terminal auf Feldgröße zurechtstutzen lassen. Wenn das Terminal keine abgefahrene Ausgabeoptimierung hat, sollte das einer Animation ähnlich dahinflimmern |
| | |
| | #14 (permalink) |
| Registriert seit: 30.12.08 ![]() Likes: 0 | Hey ho, hier eine einfach Java-Konsolen-Lösung mit quasi-unendlichem Spielfeld. Als Ausganspunkt ist momentan das "Indi" vorprogrammiert. Code: import java.util.*;
public class GameOfLife {
private boolean field[][];
public GameOfLife() {
}
public GameOfLife(int size) {
this.field = new boolean[size][size];
initField();
// I
field[1][1] = true;
field[2][1] = true;
field[3][1] = true;
field[4][1] = true;
field[5][1] = true;
field[3][2] = true;
field[3][3] = true;
field[3][4] = true;
field[3][5] = true;
field[2][5] = true;
field[1][5] = true;
field[4][5] = true;
field[5][5] = true;
// n
field[7][2] = true;
field[7][3] = true;
field[7][4] = true;
field[7][5] = true;
field[8][2] = true;
field[9][2] = true;
field[10][3] = true;
field[10][4] = true;
field[10][5] = true;
// d
field[12][3] = true;
field[12][4] = true;
field[12][5] = true;
field[15][3] = true;
field[15][4] = true;
field[15][5] = true;
field[13][3] = true;
field[14][3] = true;
field[13][5] = true;
field[14][5] = true;
field[15][2] = true;
field[15][1] = true;
// i
field[17][1] = true;
field[17][3] = true;
field[17][4] = true;
field[17][5] = true;
printField(0);
try{
Thread.sleep(1000);
}catch(InterruptedException ie) {
System.out.println("Error: " + ie);
}
}
public static void main(String[] args) {
GameOfLife life = new GameOfLife(35);
life.startGame();
}
public void startGame() {
int step = 0;
while(true) {
if(calcNextStep()){
System.out.println("Final state reached!");
break;
}
step++;
printField(step);
try{
Thread.sleep(100);
}catch(InterruptedException ie) {
System.out.println("Error: " + ie);
}
}
}
private boolean calcNextStep() {
LinkedList<Change> list = new LinkedList<Change>();
for(int y = 0; y < field.length; y++) {
for(int x = 0; x < field.length; x++) {
// dead cells with exact 3 living neighbors come alive
if(!field[x][y]) {
if(getNeighbors(x,y) == 3) {
list.add(new Change(x,y,true));
}
}
// living cells with less than 2 living neighbors die
if(field[x][y]) {
if(getNeighbors(x,y) < 2) {
list.add(new Change(x,y,false));
}
}
// living cells with 2 or 3 living neighbors stay alive
if(field[x][y]) {
if(getNeighbors(x,y) == 2 || getNeighbors(x,y) == 3) {
}
}
// living cells with more than 3 living neighbors die
if(field[x][y]) {
if(getNeighbors(x,y) > 3) {
list.add(new Change(x,y,false));
}
}
}
}
Change tmp;
boolean endGame = true;
while((tmp = list.poll()) != null) {
endGame = false;
field[tmp.getX()][tmp.getY()] = tmp.getVal();
}
return endGame;
}
private int getNeighbors(int x, int y) {
int[] pos = new int[2];
int neighbors = 0;
for(int i = 1; i <= 8; i++) {
pos = getDir(x,y,i,field.length);
if(field[pos[0]][pos[1]]) {
neighbors++;
}
}
return neighbors;
}
private void initField() {
for(int y = 0; y < field.length; y++) {
for(int x = 0; x < field.length; x++) {
field[x][y] = false;
}
}
}
private void printField(int step) {
System.out.print("\033[2J");
System.out.flush();
String out = "Game of Life -- Step " + step + "\n";
for(int i = 0; i <= field.length; i++) {
out += " =";
}
out += "\n";
for(int y = 0; y < field.length; y++) {
for(int x = 0; x < field.length; x++) {
out += " ";
if(field[x][y]) {
out += "X";
} else {
out += "-";
}
}
out += "\n";
}
for(int i = 0; i <= field.length; i++) {
out += " =";
}
out += "\n";
System.out.println(out);
}
private int[] getDir(int x, int y, int dir, int length) {
int coords[] = new int[2];
coords[0] = 0;
coords[1] = 0;
switch(dir) {
case 1:
coords[0] = x;
coords[1] = y-1;
if(coords[1] < 0) {
coords[1] = length-1;
}
break;
case 2:
coords[0] = x+1;
coords[1] = y-1;
if(coords[0] > length-1) {
coords[0] = 0;
}
if(coords[1] < 0) {
coords[1] = length-1;
}
break;
case 3:
coords[0] = x+1;
coords[1] = y;
if(coords[0] > length-1) {
coords[0] = 0;
}
break;
case 4:
coords[0] = x+1;
coords[1] = y+1;
if(coords[0] > length-1) {
coords[0] = 0;
}
if(coords[1] > length-1) {
coords[1] = 0;
}
break;
case 5:
coords[0] = x;
coords[1] = y+1;
if(coords[1] > length-1) {
coords[1] = 0;
}
break;
case 6:
coords[0] = x-1;
coords[1] = y+1;
if(coords[0] < 0) {
coords[0] = length-1;
}
if(coords[1] > length-1) {
coords[1] = 0;
}
break;
case 7:
coords[0] = x-1;
coords[1] = y;
if(coords[0] < 0) {
coords[0] = length-1;
}
break;
case 8:
coords[0] = x-1;
coords[1] = y-1;
if(coords[0] < 0) {
coords[0] = length-1;
}
if(coords[1] < 0) {
coords[1] = length-1;
}
break;
default:
}
return coords;
}
public class Change {
private int x;
private int y;
private boolean value;
public Change() {
}
public Change(int valX, int valY, boolean val) {
this.x = valX;
this.y = valY;
this.value = val;
}
public void setVal(boolean val) {
this.value = val;
}
public boolean getVal() {
return this.value;
}
public void setX(int val) {
this.x = val;
}
public int getX() {
return this.x;
}
public void setY(int val) {
this.y = val;
}
public int getY() {
return this.y;
}
}
} cByte |
| | |
| | #15 (permalink) |
| Registriert seit: 13.07.10 ![]() Likes: 0 | Hallo, das ist ja mal wirklich ne super Idee für ne Programmieraufgabe :-) Hab da mal versucht nen anderen Ansatz zu wählen, indem ich alle aktiven Zellen in einer Liste verwalte und entsprechend immer nur die aktiven Zellen und deren Nachbarn abklappere. Leider wird das ab einer gewissen Anzahl von Zellen aber zu langsam, so dass ich im Moment auch schon wieder an anderen Lösungen bastel. Dafür hab ich aber immerhin ne einfach Zoom Funktion reingebastelt... ![]() Beim Start kann man einfach die Zellen per Maus setzen und dann das Spiel mit der Leertaste starten/stoppen Ach ja, Code in Python + Pygame (und mit Sicherheit verbesserungsbedürftig Code: #!/usr/bin/python
#notwendigen Kram importieren
import pygame
from sys import exit
#einige Variablen vordefinieren
#die seltsamen Werte bei width & height liegen daran dass das für mein Netbook
#die optimale Auflösung ist ;-)
width=800
height=400
cellColor = [0,0,255]
bgcolor = [255,255,255]
#Starte mit einem Zoom Faktor (entspricht Breite und Höhe einer Zelle in Pixel) von 10
zoomFactor = 10
cycle = 0
#Das Spiel startet erst nach Drücken der Leertaste!
running = False
#die Liste, welche später zur Verwaltung der aktiven Zellen genutzt wird
cellList = []
def initGame(width=800, height=400):
size = width, height
global screen
global cellList
screen = pygame.display.set_mode(size)
screen.convert()
def toggleCell(pos):
global cellList
if checkField(pos):
cellList.remove(pos)
else:
cellList.append(pos)
def checkField(pos):
try:
cellList.index(pos)
except ValueError:
return 0
return 1
def getNeighbors(pos):
posx, posy = pos
pattern = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]]
pattern = [[(x+posx),(y+posy)] for x,y in pattern]
return pattern
def checkNeighbors(pos):
neighborhood = getNeighbors(pos)
tmp = neighborhood[:]
counter = 0
for npos in tmp:
if checkField(npos):
counter = counter + 1
neighborhood.remove(npos)
return counter, neighborhood
def checkNeighborsEmpty(pos):
neighborhood = getNeighbors(pos)
counter = 0
for npos in neighborhood:
counter = counter + checkField(npos)
return counter
def checkRules():
global cycle
cycle=cycle+1
global cellList
print len(cellList)
tmpCellList = cellList[:]
for cell in cellList:
neighbors, tmpEmpty = checkNeighbors(cell)
if (neighbors < 2 or neighbors > 3):
tmpCellList.remove(cell)
for Emptycell in tmpEmpty:
try:
tmpCellList.index(Emptycell)
except ValueError:
if (checkNeighborsEmpty(Emptycell) == 3): tmpCellList.append(Emptycell)
cellList = tmpCellList
def zoomOut():
global zoomFactor
zoomFactor = zoomFactor -1
if(zoomFactor < 1):
zoomFactor = 1
def drawCell(pos,color = cellColor):
global screen
x,y = pos
if (x < 0 or y < 0):
return
if ((x*zoomFactor >= (screen.get_width()-zoomFactor)) or (y*zoomFactor >= (screen.get_height()-zoomFactor))):
zoomOut()
x = x*zoomFactor
y = y*zoomFactor
cell_rect = pygame.Rect(([x,y]),([zoomFactor,zoomFactor]))
screen.fill(color,cell_rect)
def drawAllCells():
for pos in cellList:
drawCell(pos)
def redrawScreen():
screen.fill(bgcolor)
drawAllCells()
pygame.display.flip()
def gameLoop():
while 1:
redrawScreen()
for event in pygame.event.get():
if (event.type == pygame.QUIT):
print "Quit in Cycle: ", cycle
sys.exit()
if (event.type == pygame.KEYDOWN):
if(event.key==32):
global running
if(running == False): running = True
else: running = False
if (event.type == pygame.MOUSEBUTTONDOWN):
x,y = pygame.mouse.get_pos()
x = x/zoomFactor
y = y/zoomFactor
toggleCell([x,y])
if (running):
checkRules()
initGame()
gameLoop() |
| | |
![]() |
| | |
| |
| Themen-Optionen | |
| Ansicht | |
| |