Buch Cover Buch Cover Buch Cover Buch Cover

Web-Code: - Webcode Help

Conways Game of Life (Simulationen)

ConwaysJohn H. Conway, englischer Mathematiker (* 1937) Game of Life ist eine Populations-Simulation, die in einem Raster (beliebig großes Schachbrett) Zellen überleben, sterben oder neu bilden lässt. Das Überleben oder Neubilden von Zellen hängt allein von ihren umliegenden acht Quadraten ab.

Es gelten die folgenden Regeln:

  • Wenn eine Zelle höchstens eine Nachbarzelle hat, stirbt sie an Vereinsamung. Das heißt, sie wird nicht in die nächste Generation übernommen.
  • Wenn eine Zelle vier oder mehr Nachbarzellen hat, so stirbt sie an Übervölkerung. Das heißt, auch sie wird nicht in die nächste Generation übernommen.
  • Hat eine Zelle zwei oder drei Nachbarzellen, so überlebt sie. Das bedeutet, sie wird in die nächste Generation übernommen.
  • Wenn ein leeres Quadrat in den umliegenden acht Quadraten genau drei Nachbarzellen hat, dann entsteht dort durch Vermehrung eine neue Zelle in der nächsten Generation.

Schreiben Sie nun ein Programm, das ein 20x20-Raster Boole'scher Werte mit zufälligen Zellen füllt. (Eine Wahrscheinlichkeit von 25%, dass ein Quadrat eine Zelle enthält, hat sich in Tests als spannend erwiesen.)

Programmieren Sie den "Überlebensschritt" nach obigen Regeln und geben Sie einige Generationen aus.

0 Kommentare

Bitte melde dich an um einen Kommentar abzugeben

3 Lösung(en)

import java.util.Scanner;


public class GameOfLife {
  public static void main(String[] args) {
    new GameOfLife().top(); }

  int   KANTENLAENGE =   30 ;
  float FUELLFAKTOR  = 0.25f;
  
  boolean feld [][];
  
  
  void top() {
    initialisiereFeld(KANTENLAENGE);
    fuelleFeld();
    boolean weiter;
    weiter = true;
    while(weiter) {
        zeigeFeld();
        naechsteGenerationFeld();
        weiter = weiterMachen(); } 
  }
 

  void fuelleFeld() {
    int x = 0;
    while(x < kantenLaenge()) {
        fuelleZeile(x);
        x = x + 1; }
  }


  void fuelleZeile(int x) {
    int y = 0;
    while(y < kantenLaenge()) {
        if(Math.random() < FUELLFAKTOR) {
            feld[x][y] = true; }
        y = y + 1;    }
  }


void naechsteGenerationFeld() {
    boolean[][] feldcpy = new boolean[kantenLaenge()][kantenLaenge()]; // quadratisch
    int x = 0;
    while(x < kantenLaenge()) {
        naechsteGenerationZeile(feldcpy, x);
        x = x + 1;  }
    feld = feldcpy;  }


  void naechsteGenerationZeile(boolean[][] feldcpy, int x) {
    int y = 0;
    while(y < kantenLaenge()) {
        feldcpy[x][y] = regel(x, y); 
        y = y + 1;}
  }
  

  int kantenLaenge() {
    return feld.length; }


  /**
   * Es wird geprüft, ob an Stelle x,y ein (evtl. neues) "Bakterium" entsteht.
   * @return
   */
  boolean regel(int x, int y) {
    int anzahlLebende = totalIn3x3(x, y);
    // Vereinsamt oder verhungert:
    if(anzahlLebende < 3 || anzahlLebende >4) {
        return false; }
    // Überlebt
    if(feld[x][y] && (3 == anzahlLebende || 4 == anzahlLebende)) {
        return true; }
    //  neu geboren
    if(!feld[x][y] && (3 == anzahlLebende)) {
        return true;    }
    // nicht neu geboren, da zu wenig oder zu viele Nachbarzellen.
    return false; }


/**
 * Wie viele Felder "leben" im 3x3-Feld um (x, y) inklusive (x, y)
 */
  int totalIn3x3(int x, int y) {
    int xStart = min(x);
    int xEnd   = max(x);
    int yEnd   = max(y);
    int summe = 0;
    while(xStart <= xEnd) {
        int yStart = min(y);
        while(yStart <= yEnd) {
            if(feld[xStart][yStart]) {
                summe = summe + 1; }
            yStart = yStart + 1; }
        xStart = xStart + 1; }
    return summe;
  }


  /**
   * Minimalwert im 3x3 Feld = 0 oder >0
   * @param xy x or y
   */
  int min(int xy) {
    return Math.max(0, xy - 1); }

  
  /**
   * Maximalwert im 3x3 Feld = kantenLaenge -1 oder kleiner
   * @param xy x or y
   */
  int max(int xy) {
    return Math.min(xy + 1, kantenLaenge() - 1); }


  void zeigeFeld() {
    for(boolean [] zeile : feld) {
        for(boolean feld : zeile) {
            if(feld) {
                System.out.print('*'); }
            else {
                System.out.print(' ');
            }
        }
        System.out.println();    }  
  }

  
  void initialisiereFeld(int groesse) {
    feld = new boolean[groesse][groesse];   }

  
  boolean weiterMachen() {
    Scanner sc = new Scanner(System.in);
    System.out.println("Weiter (ja, nein)? :");
    String eingabe;
    eingabe = sc.next();
    return ! eingabe.startsWith("n"); }

} // end of class GameOfLive
                
// Processing
// grafische Loesung
// Mausklick loest nächste Generation aus
// by Igo Schaller

int Kantenlaenge = 10;
gameOfLife Spiel = new gameOfLife();
PFont schrift;

// setup() wird beim Start einmal ausgefuehrt
void setup() {
  background(200,200,200);
  stroke(100,100,100);
  size(520,520);
  smooth();
  schrift = loadFont("AlbaSuper-40.vlw");
  Spiel.zufaelligFuellen();
  Spiel.zeichnen();
  noLoop();
}

void draw() {
  background(255);
  Spiel.evolution();
  Spiel.zeichnen();
}

void mousePressed() {
  redraw();  // führt den Code in draw() einmal aus  
}

// Klasse gameOfLife
class gameOfLife {
  float StartZufall = 0.25;
  boolean[][] spielfeld = new boolean[Kantenlaenge][Kantenlaenge];  // 2D-Array mit Diemsion Kantenlaenge
  int Generation;

  // Konstruktor
  gameOfLife() {
    // Spielfeld wird mit lauter toten Zellen (=false) gefuellt
    for (int j = 0; j < Kantenlaenge; j++) {        // j geht die Zeilen des Feldes durch
      for (int i = 0; i < Kantenlaenge; i++) {      // i geht die Spalten des Feldes durch
        spielfeld[i][j] = false; 
      }
    }
  }

  // Zufaellige Startpopulation
  void zufaelligFuellen() {
    for (int j = 0; j < Kantenlaenge; j++) {
      for (int i = 0; i < Kantenlaenge; i++) {
        //wenn die Zufallszahl kleiner dem Startzufall ist, so wird die Zelle lebendig (=true)
        if (random(1) < StartZufall) {
          spielfeld[i][j] = true; 
        }
      }
    }
  }

  // naechste Generation
  void evolution()  {
    boolean[][] naechsteGeneration = new boolean[Kantenlaenge][Kantenlaenge];
    boolean Antwort;

    //naechste Generation berechnen
    for (int j = 0; j < Kantenlaenge; j++) {
      for (int i = 0; i < Kantenlaenge; i++) {
        Antwort = LebenOderTod(i,j);
        if (Antwort == true) {
          naechsteGeneration[i][j] = true; 
        }
        else
        {
          naechsteGeneration[i][j] = false; 
        }
      }
    }
    // berechnete Generation auf Spielfeld uebertragen
    for (int j = 0; j < Kantenlaenge; j++) {
      for (int i = 0; i < Kantenlaenge; i++) {
        spielfeld[i][j] = naechsteGeneration[i][j]; 
      }
    }    
  }

  // Methode berechnet ob eine Zelle aufgrund der Regeln lebend oder tod ist
  boolean LebenOderTod(int xPos, int yPos) {  
    int anzLeben;

    anzLeben = anzahlLeben3x3(xPos, yPos);
    // vereinsamt oder verhungert
    if (anzLeben < 3 || anzLeben > 4) {
      return false; 
    }
    // überlebend
    if (spielfeld[xPos][yPos] && (anzLeben == 3 || anzLeben == 4 )) {
      return true; 
    }
    // geboren
    if (!spielfeld[xPos][yPos] && anzLeben == 3) {
      return true; 
    }
    // nicht neu geboren, da zu viele Nachbarn
    return false;
  }

  // Methode zaehlt wieviele Zellen im 3x3 Quadrat um eine Zelle herum inkl. der Zelle selber leben
  int anzahlLeben3x3(int x, int y) {     
    int resultat = 0;
    for (int j = y-1; j <= y+1; j++) {
      for (int i = x-1; i <= x+1; i++) {
        if (i>=0 && i<Kantenlaenge && j>=0 && j<Kantenlaenge) {   
          if (spielfeld[i][j] == true) {
            resultat++; 
          }
        }  
      }
    } 
    return resultat;
  }

  // die Population zeichnen
  void zeichnen(){
    background(0);
    color feldFarbe;
    float feldLaenge = width/Kantenlaenge;
    float pxPosX, pxPosY;

    // falls Feld lebend Fuellfarbe gleich Rot setzen, sonst gleich weiss setzen
    for (int j = 0; j < Kantenlaenge; j++) {
      for (int i = 0; i < Kantenlaenge; i++) {
        pxPosX = i * feldLaenge;
        pxPosY = j * feldLaenge;

        if (spielfeld[i][j] == true) {
          feldFarbe = color(255,0,0); 
        }
        else
        {
          feldFarbe = color(255,255,255); 
        }
        fill(feldFarbe);
        rect(pxPosX, pxPosY, pxPosX + feldLaenge, pxPosY + feldLaenge);
      }
    } 
  }
}
                
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

void Erstellen (const, int, int*, int*, int*, int*, int*, int*);
void NaechsteRunde (const, int, int*, int*, int*, int*, int*, int*);

int main (int argc, char** argv){

	const n=5;
	int i=0;
	int Durchgang=0;
	
	int V0[n];
	int V1[n];
	int V2[n];
	int V3[n];
	int V4[n];
	int V5[n];
	
	for (Durchgang=0; Durchgang <10; Durchgang++){ //10 Durchgaenge
		
		if (Durchgang==0){
			printf("Nach dem %i. Durchgang.\n", Durchgang);
			Erstellen (n, i, V0, V1, V2, V3, V4, V5);
		}
		
		printf("Nach dem %i. Durchgang.\n", Durchgang+1);
		NaechsteRunde(n, i, V0, V1, V2, V3, V4, V5);
	}
return 0;	
}

void Erstellen (const n,int i, int V0[n], int V1[n], int V2[n], int V3[n], int V4[n], int V5[n]){
	int Prozent = 25;
	srand(time(NULL));

	for (i=0; i<=n; i++){ // Erstellen 0. Vertikale
		
		V0[i]= (rand() %(100/Prozent));
		if (V0[i]!=1){
			V0[i]=0;
		}
		printf("%i", V0[i]);
	}
	printf("\n");
	
	for (i=0; i<=n; i++){ // Erstellen 1. Vertikale
		
		V1[i]= (rand() %(100/Prozent));
		if (V1[i]!=1){
			V1[i]=0;
		}
		printf("%i", V1[i]);
	}
	printf("\n");
	
	for (i=0; i<=n; i++){ // Erstellen 2. Vertikale
		
		V2[i]= (rand() %(100/Prozent));
		if (V2[i]!=1){
			V2[i]=0;
		}
		printf("%i", V2[i]);
	}
	printf("\n");
	
	for (i=0; i<=n; i++){ // Erstellen 3. Vertikale
		
		V3[i]= (rand() %(100/Prozent));
		if (V3[i]!=1){
			V3[i]=0;
		}
		printf("%i", V3[i]);
	}
	printf("\n");
	
	for (i=0; i<=n; i++){ // Erstellen 4. Vertikale
		
		V4[i]= (rand() %(100/Prozent));
		if (V4[i]!=1){
			V4[i]=0;
		}
		printf("%i", V4[i]);
	}
	printf("\n");
	
	for (i=0; i<=n; i++){ // Erstellen 5. Vertikale
		
		V5[i]= (rand() %(100/Prozent));
		if (V5[i]!=1){
			V5[i]=0;
		}
		printf("%i", V5[i]);
	}
	printf("\n\n");
}

void NaechsteRunde(const n, int i, int V0[], int V1[], int V2[], int V3[], int V4[], int V5[]){

	for (i=0; i<=n; i++){ // Prüfen von 0.Zeile******************************************************
		int Zaehler=0;
						
		if (V0[i-1]==1){ //Mitte Links
			Zaehler++;
		}
		if (V0[i-1]==1){ //Mitte rechts
			Zaehler++;
		}
		if (V1[i-1]==1){ //Unten links
			Zaehler++;
		}
		if (V1[i]==1){ //Unten Mitte
			Zaehler++;
		}
		if (V1[i+1]==1){ //Unten Rechts
			Zaehler++;
		}
		
		if(V0[i]==1){ //Eigentliches Feld mit Zelle
			if(Zaehler<2){ //Einsamkeit
				V0[i]=0;
				printf("%i",V0[i]);
				continue;
			}	
			if(Zaehler>3){ //Ueberbefoelkerung
				V0[i]=0;
				printf("%i",V0[i]);
				continue;
			}
		} else{
			if(Zaehler==3){ //Neue Zelle entsteht
				V0[i]=1;
				printf("%i",V0[i]);
				continue;
			}
		}
		printf("%i",V0[i]);
	}
	printf("\n");
	
	for (i=0; i<=n; i++){ // Prüfen von 1.Zeile******************************************************
		int Zaehler=0;
						
		if (V0[i-1]==1){ //Oben links
			Zaehler++;
		}
		if (V0[i]==1){ //Obern Mitte
			Zaehler++;
		}
		if (V0[i+1]==1){ //Oben Rechts
			Zaehler++;
		}
		if (V1[i-1]==1){ //Mitte Links
			Zaehler++;
		}
		if (V1[i-1]==1){ //Mitte rechts
			Zaehler++;
		}
		if (V2[i-1]==1){ //Unten links
			Zaehler++;
		}
		if (V2[i]==1){ //Unten Mitte
			Zaehler++;
		}
		if (V2[i+1]==1){ //Unten Rechts
			Zaehler++;
		}
		
		if(V1[i]==1){ //Eigentliches Feld mit Zelle
			if(Zaehler<2){ //Einsamkeit
				V1[i]=0;
				printf("%i",V1[i]);
				continue;
			}	
			if(Zaehler>3){ //Ueberbefoelkerung
				V1[i]=0;
				printf("%i",V1[i]);
				continue;
			}
		} else{
			if(Zaehler==3){ //Neue Zelle entsteht
				V1[i]=1;
				printf("%i",V1[i]);
				continue;
			}
		}
		printf("%i",V1[i]);
	}
	printf("\n");
	
	for (i=0; i<=n; i++){ // Prüfen von 2.Zeile******************************************************
		int Zaehler=0;
						
		if (V1[i-1]==1){ //Oben links
			Zaehler++;
		}
		if (V1[i]==1){ //Obern Mitte
			Zaehler++;
		}
		if (V1[i+1]==1){ //Oben Rechts
			Zaehler++;
		}
		if (V2[i-1]==1){ //Mitte Links
			Zaehler++;
		}
		if (V2[i-1]==1){ //Mitte rechts
			Zaehler++;
		}
		if (V3[i-1]==1){ //Unten links
			Zaehler++;
		}
		if (V3[i]==1){ //Unten Mitte
			Zaehler++;
		}
		if (V3[i+1]==1){ //Unten Rechts
			Zaehler++;
		}
		
		if(V2[i]==1){ //Eigentliches Feld mit Zelle
			if(Zaehler<2){ //Einsamkeit
				V2[i]=0;
				printf("%i",V2[i]);
				continue;
			}	
			if(Zaehler>3){ //Ueberbefoelkerung
				V2[i]=0;
				printf("%i",V2[i]);
				continue;
			}
		} else{
			if(Zaehler==3){ //Neue Zelle entsteht
				V2[i]=1;
				printf("%i",V2[i]);
				continue;
			}
		}
		printf("%i",V2[i]);
	}
	printf("\n");
	
	for (i=0; i<=n; i++){ // Prüfen von 3.Zeile******************************************************
		int Zaehler=0;
						
		if (V2[i-1]==1){ //Oben links
			Zaehler++;
		}
		if (V2[i]==1){ //Obern Mitte
			Zaehler++;
		}
		if (V2[i+1]==1){ //Oben Rechts
			Zaehler++;
		}
		if (V3[i-1]==1){ //Mitte Links
			Zaehler++;
		}
		if (V3[i-1]==1){ //Mitte rechts
			Zaehler++;
		}
		if (V4[i-1]==1){ //Unten links
			Zaehler++;
		}
		if (V4[i]==1){ //Unten Mitte
			Zaehler++;
		}
		if (V4[i+1]==1){ //Unten Rechts
			Zaehler++;
		}
		
		if(V3[i]==1){ //Eigentliches Feld mit Zelle
			if(Zaehler<2){ //Einsamkeit
				V3[i]=0;
				printf("%i",V3[i]);
				continue;
			}	
			if(Zaehler>3){ //Ueberbefoelkerung
				V3[i]=0;
				printf("%i",V3[i]);
				continue;
			}
		} else{
			if(Zaehler==3){ //Neue Zelle entsteht
				V3[i]=1;
				printf("%i",V3[i]);
				continue;
			}
		}
		printf("%i",V3[i]);
	}
	printf("\n");
	
	for (i=0; i<=n; i++){ // Prüfen von 4.Zeile******************************************************
		int Zaehler=0;
						
		if (V3[i-1]==1){ //Oben links
			Zaehler++;
		}
		if (V3[i]==1){ //Obern Mitte
			Zaehler++;
		}
		if (V3[i+1]==1){ //Oben Rechts
			Zaehler++;
		}
		if (V4[i-1]==1){ //Mitte Links
			Zaehler++;
		}
		if (V4[i-1]==1){ //Mitte rechts
			Zaehler++;
		}
		if (V5[i-1]==1){ //Unten links
			Zaehler++;
		}
		if (V5[i]==1){ //Unten Mitte
			Zaehler++;
		}
		if (V5[i+1]==1){ //Unten Rechts
			Zaehler++;
		}
		
		if(V4[i]==1){ //Eigentliches Feld mit Zelle
			if(Zaehler<2){ //Einsamkeit
				V4[i]=0;
				printf("%i",V4[i]);
				continue;
			}	
			if(Zaehler>3){ //Ueberbefoelkerung
				V4[i]=0;
				printf("%i",V4[i]);
				continue;
			}
		} else{
			if(Zaehler==3){ //Neue Zelle entsteht
				V4[i]=1;
				printf("%i",V4[i]);
				continue;
			}
		}
		printf("%i",V4[i]);
	}
	printf("\n");
	
	for (i=0; i<=n; i++){ // Prüfen von 5.Zeile******************************************************
		int Zaehler=0;
						
		if (V4[i-1]==1){ //Oben links
			Zaehler++;
		}
		if (V4[i]==1){ //Obern Mitte
			Zaehler++;
		}
		if (V4[i+1]==1){ //Oben Rechts
			Zaehler++;
		}
		if (V5[i-1]==1){ //Mitte Links
			Zaehler++;
		}
		if (V5[i-1]==1){ //Mitte rechts
			Zaehler++;
		}
		
		if(V5[i]==1){ //Eigentliches Feld mit Zelle
			if(Zaehler<2){ //Einsamkeit
				V5[i]=0;
				printf("%i",V5[i]);
				continue;
			}	
			if(Zaehler>3){ //Ueberbefoelkerung
				V5[i]=0;
				printf("%i",V5[i]);
				continue;
			}
		} else{
			if(Zaehler==3){ //Neue Zelle entsteht
				V5[i]=1;
				printf("%i",V5[i]);
				continue;
			}
		}
		printf("%i",V5[i]);
	}
	printf("\n");
	
}
                

Lösung von: Felix Girke (DHBW Stuttgart)

Verifikation/Checksumme:

Hier eine mögliche "Life" Population. Nach einigen Generationen stellt man immer wieder die selben Muster fest:

Muster aus Conways Game of Life

Aktionen

Bewertung

Durchschnittliche Bewertung:

Eigene Bewertung:
Bitte zuerst anmelden

Meta

Zeit: 2-4
Schwierigkeit: k.A.
Webcode: ch5c-67pm
Autor: Philipp Gressly Freimann (SANTIS Training AG)

Download PDF

Download ZIP

Zu Aufgabenblatt hinzufügen