Conways Game of Life (ArrayoutofBounds/Logik der benarchbarten Felder im 2D Array

Shardic

Mitglied
Hallo liebes Javaforum,

seit einiger Zeit lese ich mit, lerne und probiere mich in verschiedenen Dingen aus, was die Programierwelt angeht. Seit Oktober studiere ich Medieninformatik :). Und endlich! schreibe ich meinen ersten Beitrag in diesem Forum, von hoffentlich vielen.

Also, es geht um eine Aufgabe aus der Uni in der wir Conways Game of Life erstellen sollen. Dies sollen wir nur mit den Mitteln tun die wir bereits in den Vorlesungen hatten. Also: Keine verwendung der bereits in Java implementierten Klassen wie z.b. ArrayList<> usw... das nur zum verständniss. Das komplette Spiel wird in der Console gespielt und ich (versuche) stelle das Spiel als 2D Array dar welches ich mit char ' ' & char 'x' (für die Steine // Lebewesen) fülle. Das Array soll dann im Spiel nach jeder "Runde" (der Benutzer kann angeben, dass die nächste Generation berechnet werden soll) die neue Spielsteinverteilung prüfen und eventuell ein größeres Array erstellen. Beim erstellen eines neues Arrays habe ich das erste Problem:

Java:
public void wachstumPruefen() {
int einMehr = 0;
		for (int k = 0; k < naechsteGeneration.length; k++) {
			if (naechsteGeneration[0][k].hatStein() == 'x') {
				einMehr = 1;
			}
			if (naechsteGeneration[k][0].hatStein() == 'x') {
				einMehr = 1;
			}
			if (naechsteGeneration[k][naechsteGeneration.length-1].hatStein() == 'x') {
				einMehr = 1;
			}
			if (naechsteGeneration[naechsteGeneration.length-1][k].hatStein() == 'x') {
				einMehr = 1;
			}
		}
		if (einMehr != 0) {	
			dasFeld = new Spielsteine[dasFeld.length+2][dasFeld.length+2];
			initialisieren();
		}
		if (einMehr == 0) {
			for (int i = 0; i < dasFeld.length; i++) {				
				for (int j = 0; j < dasFeld.length; i++) {		
					dasFeld[i][j] = naechsteGeneration[i][j];
				}
			}
		} else if (einMehr != 0) {
			for (int i = 0; i < dasFeld.length-2; i++) {				
				for (int j = 0; j < dasFeld.length-2; i++) {			
					dasFeld[i+1][j+1] = naechsteGeneration[i][j];
				}
			}
		}
	}

Zuerst wird geschaut ob in den jeweiligen Randfeldern Steine sitzen, falls das der Fall ist wird ein größeres Spielfeld erstellt, der Problem liegt im letzten Teil, wo das Feld befüllt wird welches vergößert wurde. In einem Probedurchlauf wo er das Feld von 5*5 auf 7*7 vergößert bekomme ich eine outofbounds 5 exception. Ich verstehe absolut nicht woran es liegt... das i und j müsste ja von 0 bis maximal 4 gehen (7-2 = 5 i muss darunter sein). Sieht vllt jemand meinen Fehler ?

Das zweite was ich nicht verstehe ist bei der Überprüfung der einzelnen Felder auf Nachbarn, hier nur ein kleiner Teil wo auf jeden Fall ein Fehler liegt:

Java:
	private Spielsteine[][] hatNachbarn(Spielsteine[][] formalesFeld) {
		int nachbarn = 0;
		for (int i = 0;i < formalesFeld.length; i++) {
			for (int k = 0; k < formalesFeld[i].length; k++) {
				if (i == 0) {
					if (k != 0 && k != formalesFeld.length-1) {
						if (formalesFeld[i][k-1].hatStein() == 'x') {
							nachbarn++;
						}
						if (formalesFeld[i+1][k-1].hatStein() == 'x') {
							nachbarn++;
						}
						if (formalesFeld[i][k+1].hatStein() == 'x') {
							nachbarn++;
						}
						if (formalesFeld[i+1][k+1].hatStein() == 'x') {
							nachbarn++;
						}
					}

Danach kommen noch für alle Randfelder ähnliche Abfragen... dieser Codeteil bezieht sich auf den oberen Rand, nach meiner Logik müsste er nach der Abfrage für das Feld 0/0 im Array einen Nachbarn haben wenn auf 1/1 ein Stein liegt genauso wie in Feld 1/0 und 2/0, er speichert aber für alle diese Felder 0 Nachbarn. Erkennt vllt jemand den Logikfehler den ich hier gemacht habe ? Würde es wirklich gerne verstehen :(

Da ich verschiedene andere Dinge eh abändern muss (Habe im "Interface" Labels genutzt was wir für nicht tun sollten...) werde ich sowieso noch einen anderen Ansatz probieren und die hier gestellten Fragen entfallen für die Uni eventuell, ich möchte aber verstehen wieso bestimmte Dinge nicht funktionieren. Denn ich finde meine Denkfehler nicht will diese aber unbedingt nachvollziehen...

Ansonsten verbleibe ich mit vielen Grüßen


Shardic
 

redJava99

Bekanntes Mitglied
Hi,

in der Methode wachstumPruefen() fallen mir einige Dinge auf:

- du benutzt
Code:
int einMehr
nur für die Werte 1 und 0. Also als Wahrheitswert. Dafür gibt es den Datentyp
Code:
boolean
, der die Werte
Code:
true
und
Code:
false
annehmen kann. Den müsstet ihr schon behandelt haben, wenn ihr mit if/else arbeitet.
- Zeile 21 ist demzufolge auf ein
Code:
else
reduzierbar. Denn wenn
Code:
einMehr
nicht 0 ist, ist es in jedem Fall 1. Und der Inhalt der dritten Abfrage (ab Z. 27) könnte auch gleich in der ersten Abfrage ausgeführt werden. Die Bedingung ist die gleiche und dazwischen passiert nichts.
- Der Fehler, der zu deiner ArrayIndexOutOfBoundsException führt, ist klein, aber fatal: Die jeweils innere der verschachtelten for-Schleifen erhöht die falsche Variable (i statt j).

In der Methode hatNachbarn() laufen i und k bis zum Wert formalesFeld.length-1. Also der maximale Index für das Array. Das Addieren von 1 (Zeilen 10, 13, 16) geht folglich schief.
 

Shardic

Mitglied
Hi,

erstmal vielen Dank für die Antwort. Der erste Teil ist mir dann nach ein par Tagen auch endlich aufgegangen...

In meinem zweiten Teil hatte ich keinen Fehler im Array deswegen habe ich ja von .length auch einen abgezogen und für jeden Rand extra Abfragen definiert. Diese waren leider etwas konfus und haben dafür gesorgt, dass er eine falsche Anzahl an Nachbarn geliefert hat. Könnte aber auch an der Art und Weise gelegen haben wo bzw. wann ich neue Lebewesen eingefügt habe. Diese Probleme habe ich bereits korrigiert und es läuft... naja zumindest zum Teil.

Wenn ich das Spiel mit einem Fest definierten Array (also einem endlichen Feld) laufen lasse, läuft alles so wie gewünscht. Nur bei einer Vergrößerung des Arrays mit:

Java:
this.dasFeld = new Spielsteine[this.dasFeld+2][this.dasFeld+2];

Bekomme ich bei einem späterem Zeichnen des Arrays der auf die Instanzvariable dasFeld zugreift eine NullPointer Exception. Bin mir sicher das ich irgendwas falsch mache bzw. das ich irgendetwas noch nicht weiß. Wisst ihr das zufällig so, was ich da falsch mache? Bin auch grade noch am googeln, aber da ich höflichkeitshalber antworten wollte dachte ich, kann ja nicht schaden zu fragen ;-)

// an dem this. liegt der feher übrigens leider nicht :-(

Viele Grüße

Shardic
 
Zuletzt bearbeitet:

Neue Themen


Oben