1
import processing.core.PApplet; 
import static java.lang.System.out; 

public class GoL2 extends PApplet { 

int rectSideLength = 25; // rectSideLength = length of each side of the rectangles drawn that represent cells 
int generation = 0; 
int windowWidth = 1920; 
int windowHeight = 950; 

int[][] currentGeneration = new int[windowWidth][windowHeight]; // currentGeneration = 2D array to gold cell values of current generation 
int[][] nextGeneration = new int[windowWidth][windowHeight]; // nextGeneration = 2D array to hold cell values of next generation 

int sumOfNeighbors; 
int temporarySumOfNeighbors; 
int counter; 

public static void main(String[] args) { 
    PApplet.main("GoL2"); 

} 

public void settings() { 
    size(windowWidth, windowHeight); 

} 

int numRectWidth = width/rectSideLength; // numRectWidth = the number of rectangles wide that will fit in the x axis of window 
int numRectHeight = height/rectSideLength; // numRectHeight = the number of rectangles that will fit in the y axis of window 
               // The previous statements are here because they need the size of the frame to 
               // be set in order to accurately set the variables, lest they end up equal to 100 

/* public void setup() { 
* background(255); 
* frameRate(1); 
* for (int y = 0; y < windowHeight; y++) { // For each row, 
*  for (int x = 0; x < windowWidth; x++) { // For each element in the current row, 
*   currentGeneration[x][y] = (int) random(0, 2); // Set element (cell) equal to either 0 or 1 (on or off) 
*  } 
* } 
* } */ 

public void setup() { 
    background(255); 
    frameRate(1); 
    for (int y = 0; y < windowHeight; y++) { // For each row, 
     for (int x = 0; x < windowWidth; x++) { // For each element in the current row, 
      currentGeneration[x][y] = 0; // Set element (cell) equal to either 0 or 1 (on or off) 
     } 
    } 
    currentGeneration[25][25] = 1; 
    currentGeneration[25][26] = 1; 
    currentGeneration[25][27] = 1; 
    currentGeneration[26][27] = 1; 
    currentGeneration[27][26] = 1; 

} 

public void draw() { 
    numRectWidth = width/rectSideLength; 
    numRectHeight = height/rectSideLength; 

    displayCurrentGeneration(); 
    try { 
     Thread.sleep(2); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

    fill(255, 20, 147); 
    textSize(30); 
    text(generation, 20, 30); 

    textSize(10); 
    text("25,25", 625, 645); 
    text("24,27", 600, 695); 
    text(generation, 580, 695); 
    generation++; 
    generateNextGeneration(); 

} 

public void displayCurrentGeneration() { 
    background(255); 
    for (int y = 0; y < 950; y++) { // For each row, 
     for (int x = 0; x < 1920; x++) { // For each element in the current row, 
      if (currentGeneration[x][y] == 0) { // If element equals zero, make rectangle white 
       fill(255); 
       stroke(0); 
      } else if (currentGeneration[x][y] == 1) { // If element equals one, make rectangle black 
       fill(0); 
       stroke(255); 
      } else { 
       out.println("Inappropriate value for currentGeneration[" + x + "][" + y + "]. Value: " 
         + currentGeneration[x][y] + ", generation: " + generation); 
      } 
      rect(x * rectSideLength, y * rectSideLength, rectSideLength, rectSideLength); // Display rectangle (cell) 
     } 
    } 

    // out.println("Generation " + generation); 

} 

public void generateNextGeneration() { 
    out.println("Generating gen " + generation); 
    for (int y = 1; y < numRectHeight - 1; y++) { // For each row, 
     for (int x = 1; x < numRectWidth - 1; x++) { // For each element in the current row, 
      sumOfNeighbors = 0; 
      sumOfNeighbors = getSumOfNeighbors(x, y); 
      if (sumOfNeighbors != 2 && sumOfNeighbors != 3) { // Death 
       nextGeneration[x][y] = 0; 
      } else if (sumOfNeighbors == 3 && currentGeneration[x][y] == 0) { // Birth 
       nextGeneration[x][y] = 1; 
      } else if ((sumOfNeighbors == 2 || sumOfNeighbors == 3) && currentGeneration[x][y] == 1) { // Stasis 
       nextGeneration[x][y] = 1; 
      } 
     } 
    } 
    currentGeneration = nextGeneration.clone(); 
} 

public int getSumOfNeighbors(int xAxis, int yAxis) { 
    temporarySumOfNeighbors = 0; 

    for (int i = -1; i < 2; i++) { 
     for (int j = -1; j < 2; j++) { 
      if (xAxis == 24 && yAxis == 27 && j != 0 && i != 0) { 
       out.println("X" + j + ", Y" + i + ":: " + currentGeneration[xAxis + j][yAxis + i]); 
      } else if (xAxis == 24 && yAxis == 27 && j == 0 && i != 0) { 
       out.println("X" + ", Y" + i + ":: " + currentGeneration[xAxis + j][yAxis + i]); 
      } else if (xAxis == 24 && yAxis == 27 && j != 0 && i == 0) { 
       out.println("X" + j + ", Y" + ":: " + currentGeneration[xAxis + j][yAxis + i]); 
      } else if (xAxis == 24 && yAxis == 27 && j == 0 && i == 0) { 
       out.println("X" + ", Y" + ":: " + currentGeneration[xAxis + j][yAxis + i]); 
      } 
      temporarySumOfNeighbors += currentGeneration[xAxis + j][yAxis + i]; 
     } 
    } 
    temporarySumOfNeighbors -= currentGeneration[xAxis][yAxis]; 
    if (temporarySumOfNeighbors > 8) { 
     out.println("temporarySumOfNeighbors > 8: " + temporarySumOfNeighbors); 
    } 
    if (xAxis == 24 && yAxis == 27) { 
     out.println("Generation: " + generation + "- " + xAxis + ", " + yAxis + ": " + temporarySumOfNeighbors); 
    } 

    return temporarySumOfNeighbors; 

} 

} 

http://pastebin.com/GH51hXzJWarum sind die Generationen in meinem Spiel des Lebens (mit Verarbeitung) außer Betrieb?

Ich bin ein Anfänger versuchen, das Spiel des Lebens zu kodieren, und ich bin nicht sicher, wie die Quelle meiner Probleme zu finden. Ich habe das Spiel so eingestellt, dass ich einfach mit einem einfachen Segelflugzeug im Setup starte und glaube, dass ich die Auswirkungen des Problems gefunden habe.

Ich setze Marker auf die Zellen, um sie zu verfolgen. Wenn Sie Zelle (24,27) ansehen, sehen Sie mindestens ein Beispiel des Problems. In der Konsole drucke ich die Umgebung dieser Zelle während des ganzen Laufs des Programms aus. Es scheint irgendwie die Nachbarschaft zu erkennen, die (24,27) in Generation 2 in Generation 1 haben wird und umgekehrt (unter der Annahme, dass die erste Generation Generation 0 ist). Ich bin mir nicht sicher, wie ich das erklären soll, aber wenn Sie die Konsolenausgabe untersuchen und sich die Nachbarschaften ansehen, sehen Sie, dass sie die Nachbarschaft von Generation 2 in Generation 1 erkennt und umgekehrt. Wenn (24,27) in Generation 1 3 Nachbarn sind, wird es erst in Generation 3 lebendig, während es in Generation 2 nur 2 Nachbarn hat.

Bitte lassen Sie mich wissen, wenn Sie irgendwelche Fragen haben, finde ich es schwierig, mein Problem zu erklären.

Das Problem wird mehr hier erklärt: http://imgur.com/gallery/iRc07/new

Danke

Antwort

0

Dies ist die wichtigste Ursache des Problems:

currentGeneration = nextGeneration.clone(); 

Man könnte denken, dass Linie alles von nextGeneration in currentGeneration kopiert und es tut ... aber nicht so wie du denkst.

Die Variable nextGeneration ist ein 2D-Array. Mit anderen Worten, es ist ein Array von Arrays. Mit anderen Worten, sind die in nextGeneration enthaltenen Werte Arrays.

Wenn Sie die clone()-Funktion eines Arrays aufrufen, kopiert es die Werte des alten Arrays in ein neues Array. Da ist dein Problem: deine Werte sind Arrays. So kopiert es die Arrays, nicht die Werte in diesen zweiten Arrays.

Aus diesem Grund zeigen sowohl nextGeneration als auch currentGeneration auf die gleichen Arrays. Wenn Sie nun die nächste Generation berechnen, ändern Sie die Arrays der aktuellen Generation. Dies funktioniert nicht, da die Game of Life Berechnung zwei separate Arrays benötigt.

Mit anderen Worten, Sie machen eine flache Kopie der Arrays.

Dies könnte einfacher sein, mit einem einfacheren Programm zu erklären:

public class Test { 
    public static void main(String... args){ 

     //create an array 
     int[][] array = {{1, 2, 3}, {4, 5, 6}}; 

     //clone the array 
     int[][] arrayTwo = array.clone(); 

     //change the original array 
     array[0][0] = 99; 

     //second array has also changed! 
     System.out.println(arrayTwo[0][0]); 
    } 
} 

Lange Rede kurzer Sinn: Sie sollten so gut wie nie die clone()-Funktion verwenden.

Sie könnten Ihr Problem beheben, indem Sie eine tiefe Kopie des Arrays erstellen. Es gibt Bibliotheken, die das für Sie behandeln, oder Sie könnten Serialisierung verwenden, oder schreiben Sie einfach Ihre eigene verschachtelte for-Schleife.

Aber eine noch einfachere (und ich würde richtiger argumentieren) Lösung wäre: Stop Verwendung von Variablen auf Klassenebene, wenn Sie sie nicht brauchen.

Das clone() Problem wäre kein Problem, außer dass Sie nextGeneration als Variable auf Klassenebene verwenden. Dies bedeutet, dass es seinen Wert zwischen den Aufrufen an generateNextGeneration() behält. Und da dieser Wert auf die Arrays in currentGeneration zeigt, verursacht das alle Probleme.

Sie behandeln dieses Problem bereits mit Ihren anderen Variablen: Beachten Sie, wie Sie die sumOfNeighbors und temporarySumOfNeighbors zurücksetzen, bevor Sie sie verwenden. Sie könnten dasselbe mit der Variablen nextGeneration machen.

Aber ich würde einen Schritt weiter gehen und alle drei dieser Variablen auf Klassenebene loswerden. Verschieben Sie ihre Deklarationen in die Funktionen, die sie verwenden, damit Sie sich nicht darum kümmern müssen, dass sie ihre Werte zwischen Funktionsaufrufen beibehalten.

Zwei weitere Notizen, während ich schon dabei bin:

Sie sollten wirklich nicht Thread.sleep() Anruf aus der draw() Funktion (oder eine Event-Funktion). Legen Sie die Bildrate fest und lassen Sie die Verarbeitung von Timing für Sie verarbeiten.

Sie verwenden eine Tonne von Zellen, die Sie nicht zeichnen. Ihr Array ist 1920 x 950, aber Sie zeichnen nur einen kleinen Prozentsatz dieser Zellen. Das verschwendet eine Menge CPU-Zeit auf Zellen, die Sie nie zeigen. Wie ich in Ihrer anderen Frage gesagt habe, müssen Sie vorsichtiger zwischen Pixelkoordinaten und Array-Koordinaten unterscheiden.

Wie auch immer, das war eine gute Frage. Ich denke du kommst näher. Sie müssen nur diese zusätzlichen Zellen loswerden, und Sie werden in ziemlich guter Form sein. Viel Glück.

PS: Ich werde einen Tag zu Ihrer Frage hinzufügen. Wenn Sie in der Zukunft Fragen haben, ist es wahrscheinlich eine gute Idee, dieses Tag einzubinden. Sonst werde ich es nicht sehen. : p

+0

Vielen Dank für die Hilfe, ich schätze es wirklich. Ich habe das Spiel des Lebens abgeschlossen und trotz ein bisschen (Input?) Verzögerung funktioniert es perfekt. Ich werde zu einem späteren Zeitpunkt in Ihre Vorschläge bezüglich der Arrays innerhalb der Funktionen schauen, denn jetzt bin ich einfach glücklich, dass es funktioniert. – sirmax224

+0

@ sirmax224 Das ist großartig. Wenn Sie nicht von meinem Profilbild erzählen können, bin ich ein großer Fan des Spiels des Lebens (und Verarbeitung!). Freut mich zu hören, dass du es sortiert hast. Ich würde vermuten, dass Ihre Verzögerung dadurch verursacht wird, dass Sie eine Reihe von Zellen zeichnen, die Sie nicht zeigen. Lassen Sie mich wissen, wenn Sie weitere Fragen haben! –

Verwandte Themen