# Game of Life - Nachbarn zählen



## DaPatrick (4. Nov 2010)

Hi Leute,

hab folgendes Problem: Habe ein Programm mit dem ich bei einer wahlweise begrenzten oder unbegrenzten Welt ein Spielfeld erzeugen kann und davon die Generationen berechne und auf der Konsole ausgebe. Es funktioniert bisher alles bis auf, dass er mir die Generationen falsch berechnet..

Den Fehler finde ich leider nicht und daher würde ich euch bitten, ob ihr ihn seht und mir weiterhelfen könnt 

[Java] ...
  /** Startet das Spiel und entwickelt die naechste Generation
     */
    public void start() {

       /** Zunaechst muss eine Kopie der Welt erstellt werden,
        *   die aber nur zur Entwicklung der Generation gebraucht 
        *   wird und sonst keine weitere Anwendung hat  
        *   @param zeile: Laufvariable zum Durchlauf aller Zeilen
        *   @param spalte: Laufvariable zum Durchlauf aller Spalten
        */   

       this.welt_kopie = new boolean[this.z][this.s];

       for (int zeile = 0; zeile < this.z; zeile++) {
          for (int spalte = 0; spalte < this.s; spalte++) {
             welt_kopie[zeile][spalte] = this.welt[zeile][spalte];
          }
       }

          /** Durchlaufe das Spielfeld nach Zeilen und Spalten
           */
	  for(int zeile = 0; zeile < this.z; zeile++) {
		for(int spalte = 0; spalte < this.s; spalte++) {


                        /** Berechne die Nachbar der Zellen und nach den Spielregeln schließlich die naechste Generation
                         *   Spielregeln: 1. Eine Zelle bleibt lebendig, wenn sie 2 oder 3 lebendige Nachbarn besitzt
                         *                2. Eine Zelle wird geboren, wenn sie genau 3 lebendige Nachbarn besitzt
                         *                3. Eine Zelle stirbt, wenn sie 0, 1 oder mehr als 3 Nachbarn besitzt
                         */

			if(welt[zeile][spalte] == true) {

				/** Regel 1 */
				if(getNachbarn(zeile, spalte)==2 || getNachbarn(zeile, spalte)==3) welt_kopie[zeile][spalte] = true;

					/** Regel 3 */
					else welt_kopie[zeile][spalte] = false;
			}
				 else {
					/** Regel 2 */
					//if(getNachbarn(zeile, spalte)==3) welt_kopie[zeile][spalte] = true;
				 }
                }
	  }


		this.welt = this.welt_kopie;


    }





/** get-Methoden */

    public boolean showNachbarn(int z, int s) {

    	if(begrenzt == true) {

    		if(z==-1 || s==-1 || s==getSpalten() || z==getZeilen()) {

    			return false;
    		}
    		else return getZelle(z, s);
    	}
    	else {
    		if(s==-1)
    		{
    			s=getSpalten()-1;
    		}
    		if(z==-1)
    		{
    			z=getZeilen()-1;
    		}
    		if(s==getSpalten())
    		{
    			s=0;
    		}
    		if(z==getZeilen())
    		{
    			z=0;
    		}

    		return getZelle(z, s);
    	}

    }



    /** Methode zur Bestimmung der Nachbarn
     * @param z: Zeile der Zelle
     * @param s: Spalte der Zelle
     * @param nachbar: Anzahl der lebendigen Nachbarn einer Zelle
     * @return nachbar-1: Ausgabe aller lebendigen Nachbarn abzueglich der Zelle selbst
     */
    public int getNachbarn(int z, int s) {

 	int nachbar = 0;

	 if((z+this.z)%this.z!=0 && (s+this.s)%this.s!=0) {

    		for (int zeile = z-1; zeile <= z+1; zeile++) {
	    	   for (int spalte = s-1; spalte <= s+1; spalte++) {

    			if (showNachbarn(zeile, spalte) == true) nachbar++;	
    		   }
		} 
		return nachbar-1;   	
    	 }
	   else return nachbar;	
    }
... [/Java]


----------



## Marco13 (4. Nov 2010)

Beachte auch die Trennung von Model, View und Controller


----------



## DaPatrick (4. Nov 2010)

Habe ich 

Hab eine CLI, die eine Datei einlesen kann und daraus dann die Welt auf der Konsole erstellt  Allerdings wie gesagt nicht die richtigen Generationen 

Weiß jemand weiter? Was ich da vllt falsch gemacht habe?

Danke im Voraus


----------



## SlaterB (4. Nov 2010)

http://www.java-forum.org/java-basics-anfaenger-themen/107993-game-life.html
hier ist noch so ein Programm, 
zwar nicht zur Kopie zu empfehlen, aber siehe meine Antworten dort hinsichtlich Logging, besonders Posting
http://www.java-forum.org/java-basics-anfaenger-themen/107993-game-life.html#post691721


----------



## Marco13 (4. Nov 2010)

Ist halt so schwer nachzuvollziehen, aber bei
 if(welt[zeile][spalte] == true) {
sieht's aus als würden nur Zellen lebendig werden können, die _sowieso_ schon leben...


----------



## Androbin (17. Apr 2014)

Ich hab es auch eimal nachprogrammiert! Wer es sich aus Problem-behandelnden Gründen
noch mal genauer ansehen will, kann es sich hier downloaden!


----------



## Barista (18. Apr 2014)

Ich würde erst mal die Methoden anders benennen:

*showNachbarn*

Besser wäre hasNachbarn.

(Tolles Denglisch, aber ok, technische Sachen Englisch, fachliche Angelegenheiten Deutsch)



*getNachbarn*

Besser wäre getNachbarCount.

*this.welt_kopie*

Besser wäre zellArrArr.

Ich nutze zur Benennung von Collections/Arrays nicht einfach ein nachfolgendes 's' für den englischen Plural,
sondern den jeweiligen Collection-Typ, bei einem zweidimensionalen Array eben ...ArrArr,
Beim Auspacken der jeweiligen Collection/Array wird dem aktuellen Element immer der jeweilige Name der
Collection ohne den Postfix gegeben.

Nun ist klar, dass Dein Datenmodell ein zweidimensionales boolean-Array ist.

Dann würde ich Methoden zur Prüfung der Nachbar-Position schreiben.

```
boolean hasNachbarTopLeft( int row, int col )
{
    if ( row > 0 && col > 0 )
    {
        return this.zellArrArr[ row ][ col ];
    }
    return false;
}
```

In der Methode *getNachbarCount* werden diese dann der Reihe nach aufgerufen.

Da kannst Du jeweils ein if machen:


```
int getNachbarCount( int row, int col )
{
    int count = 0;

    if ( hasNachbarTopLeft( row , col ) )
    {
        count++;
    }

    return count;
}
```

Möglich wäre aber auch dieser Stil:


```
return
    ( hasNachbarTopLeft( row , col ) ? 1 : 0 ) +
    ... und so weiter ...
```

Also möglichst kleine Methoden,
die nur etwas bestimmtes machen,
die Profis nennen das
separation of concerns.

Eventuell Zwischenschritte durch Tests mit JUnit absichern.
Ist mir jetzt aber zu anstrengend, dafür eine Anleitung zu schreiben.


----------



## strußi (18. Apr 2014)

du könntest auch so was machen


```
for (int row =0; row< matrix.length; row++){
      for (int col =0; col < matrix[ row].length; col++){
           // alle "spezialfälle abfragen( feld am oberen Rand, obere Rand und obere Ecke links rechts row=0
           // und col =0 oder col =matrix[ row].length-1
           if (row ==0 && col ==0){
                sumNachbarn = matrix[row][col+1] +matrix[row +1][col] + matrix[row +1][col+1];
           // alle seitlichen felder => col =0 und col =matrix[ row].length-1
           } else if{
             ....
           // alle "spezialfälle abfragen( feld am oberen Rand, obere Rand und obere Ecke links rechts
           // row = matrix.length-1
           // und col =0 oder col =matrix[ row].length-1
           } else{
               // alle felder um das zentrum drum rum
```

so für alle 8 spezialfälle
4 ecken und 4 ränder
 und als 9 dann den fall dass du nicht am rand bis und alle felder drum rum zählen musst/sollst
du kannst die reihenfolge auch anpassen, aber so hast du am wenigsten arbeit


----------



## JCODA (19. Apr 2014)

Oder du verwendest einfach sowas hier

http://www.java-forum.org/spiele-mu...47-conways-spiel-lebens-nachprogrammiert.html


----------

