Conways Game of Life / "Waldbrandsimulation": wieso temporäres Hilfs-Array?!

chmbw

Mitglied
Hallo,

ich habe mir mal ein paar Aufgaben zum einfachen über herausgesucht, aber ich verstehe eine Forderung nicht ganz. Die Aufgaben sind:

Einmal Conways Game of Life (auf der Konsole) programmieren.

und einmal eine "Waldbrandsimulation": Ein Array aus Objekten repräsentiert den Wald. Ein Objekt beinhaltet wiederum zwei Objekte Boden bzw. Baum. Die "Baumhöhe" wird durch Zahlen von 0 bis 5 dargestellt. Ist ein Baum abgebrannt, wird der Boden als "verbrannt" markiert. In Parzellen wo kein Baum drin steht kann der Boden auch nicht verbrennen. Das ist die grobe Aufgabenbeschreibung.

In beiden Aufgabenstellungen wird nun aber gefordert, dass ich alle Änderungen zuerst in ein "temporäres Hilfsarray" schreibe, welches ich dann am Ende, wenn das gesamte Array einmal durchitteriert wurde, in das eigentliche "Ursprungsarray" kopiere. Wo ist da der Sinn? Wieso soll ich nicht direkt mein "Ursprungsarray" manipulieren, sondern es in ein temporäres Array kopieren, dort alles ändern, und dann alles zurückkopieren?

Hoffe mir kann jemand weiterhelfen!

Viele Grüße
 
Weil du jeweils die originalen und nicht die neuen bearbeiteten Daten brauchst, wenn du durch das Array iterierst.

z.B. beim Waldbrand, wenn du berechnen sollst, ob ein entsprechender baum auch anfängt zu brennen:

Die vorgabe könnte sein:
"ein baum fängt an zu brennen, wenn ein baum direkt neben an auch brennt."

2x2 Array wald
[baum 1: brennt, baum 2: brennt nicht]
[baum 3: brennt nicht, baum 4: brennt nicht]

Wenn du dir jetzt überlegst, welche bäume in der nächsten iteration brennen sollten, dann sind das baum 3 und baum 2, denn die stehen direkt neben dem brennenden baum. Nicht jedoch baum 4, denn der steht im moment neben keinem brennenden baum.

Wenn du jetzt aber über dein 2D-Array iterierst und das jeweilige Resultat reinschreibst, dann passiert folgendes.

baum 1 brennt, also nichts machen
wald[0][0] = brennt

baum 2 brennt nicht also schaue in wald[][], ob ein baum neben dran brennt: baum 1 brennt also
wald[0][1] = brennt

baum 3 brennt nicht also schaue in wald[][], ob ein baum neben dran brennt: baum 1 brennt also
wald[1][0] = brennt

baum 4 brennt nicht, also schaue in wald[][], ob ein baum neben dran brennt: baum 2 brennt (denn das hast du ja in dein array schon geschrieben) also:
wald[1][1] = brennt

Eigentlich aber sollte ja baum 4 nicht brennen...
 
erstmal herzlichen Dank für deine Antwort! 🙂
Allerdings hatte ich, um genau das Problem zu umgehen, eine Variable "inflamed" eingeführt um zu wissen, ob ich den Baum in der aktuellen Iteration angesteckt hatte oder nicht...Hat auch alles wunderbar so funktioniert wie gefordert.

Einen anderen vernünftigen Sinn als "meine Hilfsvariable" zu ersetzen kann so ein Array nicht haben? Ich bin recht unerfahren in der OOP, deshalb kamen mir der Gedanke wie "setter" bzw "getter"-Methoden, nur halt in diesmal in einer gewissen Analogie zum Array (das "Ursprungsarray" ist in meinen Beispielen private) ?! Gibt es eine sinnvolle Anwendungsform von: "ich erstelle ein identisches zweites Array, manipulier das um......zu vermeiden"?

Viele Grüße
 
Das Problem dabei ist, das in echt ein Wald gleichzeitig überall abfackeln würde, du in deinem Programm aber die Änderungen nur nacheinander durchführen kannst. So kann es passieren, dass Bäume abgefackt sind, bevor sie andere anstecken konnten. Oder allgemeiner: Änderungen an einem Teil könnten dazu führen, dass die Änderung des gesamten nicht mehr stimmt.

Das Hilfsarray ist gar nicht schlecht. Wie weit biste?
 
Hab es auch mal ausprobiert. Eine OOVariante sieht so aus, dass es für jedes Element ein eigenes Objekt mit Status und Nachbarobjekten gibt. Das Objekt besitzt eine Methode, um Änderungen an dem Status der Nachbarn vorzumerken, außerdem eine Methode, alle Änderungen durchzuführen. Dann muss nacheinander für alle Objekte die Methode zur Vormerkung der Änderung und danach dann für alle die zur Änderung aufgerufen werden.
Hoffentlich war das jetzt nicht zu arg unverständlich.🙂
 
hmm, ich meine verstanden zu haben was du meinst:

Mein Wald wird durch ein Array erzeugt, jedes Arrayelement ist quasi ein "Sektor" in meinem Wald. Jeder Sektor hat ein Objekt "boden" und ein Objekt "baum". Jetzt verpass ich jedem dieser beiden Objekte eine Methode "ändern", welche beispielsweise die Baumhöhe pro Iteration verringert etc. Eine andere Methode wäre "status": diese fragt den status der umliegenden Felder ab und setzt eine Variable die angibt, ob der Baum in dieser Runde angesteckt wurde oder schon brennt.
Sprich du hast das explizite erzeugen des Hilfsarrays mit "status" umgangen?!

War es das was du meinst, hoffe ich habe es richtig verstanden?!

Viele Grüße
 
Genau.

Du iterierst dann über alle Objekte und merkst dir, ob es Veränderungen gibt (mit einer methode) und in einer zweite iteration änderst du es dann (mit einer anderen methode, die auf die angaben der ersten methode, in unserem Fall die variable status, zurückgreift.).

Du musst nicht unbedingt Objekte wie Baum oder Boden haben, wenn diese nicht all zu viel machen. Das können auch einfach Instanzvariablen in deiner Klasse Sektor sein:

Java:
private int inflamed;
private int treeheight;

Wenn du dann komplexere Sachen mit den Objekten machen musst, dann kannst du dies immer noch auslagern.
 
Zuletzt bearbeitet:
Alles klar, herzlichen Dank!

Ich persönlich finde die Möglichkeit mit der status-variablen irgendwie "besser", da ich den Speicher nicht mit einem zusätzlichen großen Array belaste, somit müsste diese Variante auch performanter sein?!

Ich danke euch für eure Hilfe, viele Grüße

chmbw
 

Zurück
Oben