"Conways GameofLife - Vom Reader ins Array"

HalloWelt91

Mitglied
Hallo zusammen,

ich habe im Unterricht eine Aufgabe bekommen, Conways GameofLife zu programmieren.
Ich selber beschäftige mich erst seit kurzem mit Eclipse und der Programmierung generell und komme an früher Stelle meiner Arbeit leider nicht mehr weiter.
Die Aufgabenstellung:
- Einlesen einer Textdatei (mit X--> Symbol für tote Zellen und O--> Symbol für lebende Zellen) und Überführung der Daten in ein 2 dimensionales Array. Die Textdatei besteht nur aus einer gewissen Menge an Symbolen, beim Einlesen soll es eine Fehlermeldung geben, wenn die Matrix-Form nicht rechteckig ist,
es andere Symbole als X und O gibt oder die gewünschte Matrixgröße 1x1-50x50 nicht gegeben ist.
X und O symbolisieren Zellen auf einem rechteckigen Spielfeld, die je nach Eingabe den Zustand "Tot" oder "Lebendig" haben, welcher sich über mehrere Generationen unter Einflussnahme von 4 Regeln verändert. Es sollen so viele Generationen durchlaufen werden, bis ein endlicher Zustand (Alle Zellen tot oder lebendig bzw eine Endlosschleife) erreicht worden ist. Dieser endliche Zustand soll dann in einer Textdatei wieder ausgegeben werden.
Zu meinem Problem: Ich habe das Einlesen der Textdatei bereits fertig, sie wird auf Richtigkeit geprüft und in der Console ausgegeben. Dafür lasse ich in einer Schleife Zeilenlänge und Zeilenanzahl zählen und erschaffe mit diesen Daten ein 2 dimensionales Array, in welchem ich die Daten abspeichern möchte (Zeichen für Zeichen). Anbei der Code:

Anfangszustand:
XOOOO
XOOOX
OXXXO
OXXXX
OXXXX
OXXXX



[JAVA=42]
//......... (Lediglich die Prüfung der Dateirichtigkeit und die Counter fürs Array
int hallo1[][] = new int[zeilennummer][feldbreite];

// System.out.println(hallo1.length);
File datei2 = new File("c:\\Testdatei2.txt");
int c;
int zeile = 1;
int zeichen = 0;
try {
FileReader f = new FileReader(datei2);
while ((c = f.read()) != -1) {
if ((zeichen >= feldbreite)) {
zeile++;
zeichen = 1;
} else {

if (c == 88||c==79) {
zeichen++;hallo1[zeile - 1][zeichen -1] = c;
} else {

if (c != 79||c!=88) {
zeichen = zeichen;


}
}

}
if (zeile > zeilennummer) {
break;
}
}
for (int i = 0; i < zeilennummer; i++) {
for (int j = 0; j < feldbreite; j++) {
System.out.println(i + " " + j + " " + hallo1[j]);
}
}
f.close();
} catch (IOException e) {
System.out.println("Fehler: " + e.toString());

}
}
}
[/code]

AUSGABE:
0 0 88
0 1 79
0 2 79
0 3 79
0 4 79
1 0 0
1 1 88
1 2 79
1 3 79
1 4 79
2 0 0
2 1 79
2 2 88
2 3 88
2 4 88
3 0 0
3 1 79
3 2 88
3 3 88
3 4 88
4 0 0
4 1 79
4 2 88
4 3 88
4 4 88
5 0 0
5 1 79
5 2 88
5 3 88
5 4 88

Wie ihr seht, arbeite ich mit dem ASCII-Code und versuche so, nur die X und O in das Array zu überführen. Leider erzeugt der Reader beim Zeilenwechsel noch die Int-Werte 10 und 13, weshalb ich es nicht hinbekomme, das Array korrekt einzulesen. Vielleicht habt ihr dazu ja eine Idee, sollte es eine Alternatividee zu meinem Vorgehen sein, bin ich auch dafür immer offen und sehr dankbar.

Ich hoffe, dass ihr dafür eine Idee habt :)
Beste Grüße
 

SilverClaw

Aktives Mitglied
Da ich CGoL auch schon machen musste, ein Tipp vorneweg: speicher dir die Zellen direkt als boolean -Array, nicht als ASCII-Zeichen, das ist ein wenig schneller, als auch weniger fehleranfällig, da du später nicht mehr Buchstaben überprüfen musst, sondern nur noch die Möglichkeit zwischen true und false hast.
Dann würde ich erstmal zeilenweise einlesen und für jede Zeile prüfen, ob sie gleich groß ist, wie die erste. Das geht einfacher, wenn du einen BufferedReader oder Scanner um den FileReader packst.
Ab da kannst du die Zeilenbrüche wegwerfen (einfach jede nextLine() direkt an den String anfügen, dann sind die schon beim einlesen weg), jedes Zeichen durchgehen und z.B. bei 'X' ein true speichern, bei 'O' ein false und in die nächste "Zeile" des Arrays springen, wenn dein Zähler bei der Breite des Feldes angekommen ist.

(wenn da sjetz tunverständlich war, morgen früh kann ich es bestimmt besser erklären :toll:)
 

HalloWelt91

Mitglied
Wie füge ich die zeilen an einen string an? Bzw speichere ich doch dann ganze zeilen in meinem array oder nicht?
Tschudige, mir fehlt leider noch der javabezogene weitblick, um das ohne probleme umzusetzen und alles zu verstehen ;)
Also... als ziel soll stehen, direkt false oder true in meinem array stehen zu haben das hab ich hfftl richtig verstanden, das würde mir im bezug auf die zellen sicher auch einiges an code sparen. Könntest du das "wie" vielleicht für blöde nochmal spezifizieren?
 

SilverClaw

Aktives Mitglied
Wie füge ich die zeilen an einen string an?
Gar nicht. Strings sind nicht veränderbar, man kann höchstens neue Strings erschaffen, indem man z.B. String einString = einString + andererString; benutzt. Wenn man das nur ein oder zweimal machenmuss, ist das auch die einfachste Lösung. Wenn man allerdings viele Zeilen aus eine Datei auslesen will, empfiehlt sich ein StringBuilder.
Hier mal ein Beispiel, wie ich die Datei auslesen würde:

Java:
	  File conwayFile = new File("C:\\Users\\meinName\\Desktop\\conway.txt");
	  BufferedReader buffer = null;
	  try {
		 buffer = new BufferedReader(new FileReader(conwayFile));
	  } catch (FileNotFoundException e) {
		System.err.println("Eine gute Fehlermeldung");
		e.printStackTrace();
	  }
	  int width = 0;
	  int height = 0;
	  
	  if(buffer != null) {
		  StringBuilder builder = new StringBuilder(64);
		  
		  try {
			String firstLine = buffer.readLine();
			if(isValid(firstLine)) {
				width = firstLine.length();
				height++;
				builder.append(firstLine);
			} else {
				throw new IOException("Invalid first Line");
			}
			while(buffer.ready()) {
				String nextLine = buffer.readLine();
				if(isValid(nextLine)) {
					if(nextLine.length() == width) {
						builder.append(nextLine); height++;
					} else {
						throw new IOException("Line lenght does not match width!");
					}
				} else {
					throw new IOException("Invalid line after " + height);
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 try {
			buffer.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 System.out.println("Zwischenstatus:");
		 System.out.println(builder.toString());
		 System.out.println(width + " " + height);
	  }

dazu das isValid:

Java:
  private static boolean isValid(String line) {
		  
	  	for(int i = 0; i < line.length(); i++) {
	  		if(line.charAt(i) != 'X' && line.charAt(i) != 'O') return false;
	  	}
		return true;
	  }

Dadurch hätten wir nun als Ausgabe:
Zwischenstatus:
XOOOOXOOOXOXXXOOXXXXOXXXXOXXXX
5 6

Wir haben also den ganzen Dateiinhalt in einem StringBuilder, wissen, dass er richtig sein müsste und kennen die Höhe und Breite der Welt. Jetzt musst du nur noch einen boolean-Array mit der Breite * Höhe anlegen (anders herum ginge auch, ich finde das aber besser), mit einer Schleife über den String gehen und für jedes X ein true und jedes O ein false (oder anderes herum, Hauptsache du weißt, was was ist). Das dürfte mit charAt(index) gehen, man kann mit builder.toString().toCharArray() aber auch erstmal ein char-Array erhalten. Und, falls du gar nicht erst in boolean umwandeln wilst, könntest du über die Methode auch einfach Arrays aus 'X' und 'O' -chars erstellen.
Aber da lass ich dicherstmal probieren, du sollst ja auch selbst was machen. ;)
 
Zuletzt bearbeitet:

HalloWelt91

Mitglied
Vielen Dank für deine so ausführliche Antwort :)
Da ich noch nie mit boolean-Arrays gearbeitet habe, wurde gerade kurzerhand ein 2 dim. Array der Art geschrieben, auch das Füllen von diesem hat gut funktioniert. Jetzt schaffe ich es aber seid 3 Stunden nicht (an dem Problem saß ich auch gestern schon 12! Stunden mit einem Int Array, bevor die Frage an die Internetgemeinde unabdingbar wurde), das auch auf den ausgelesenen String zu adaptieren. Es wird ein kleiner blöder Denkfehler sein, aber aus dem Tunnel schaffe ich es gerade einfach nicht mehr raus :/

[JAVA=42]
System.out.println("Zwischenstatus:");
System.out.println(builder.toString());
System.out.println("Zeichen/Zeile: " + width + " Anzahl Zeilen: "
+ height);
boolean x;
boolean hallo[][] = new boolean[width][height];
for (int l = 0; l < width * height; l++) {
char t = builder.charAt(l);
if (t == 88) {
x = false;
} else {
x = true;
}
for (int k = 0; k < hallo.length; k++) {
for (int i = 0; i < hallo[k].length; i++) {
hallo[k] = x;

}
}
int i = 0;
int j = 0;
i++;
if (j == 3) {
j++;
i = 0;

}

System.out.print(hallo[j]);

}
}

}

private static boolean istgültig(String firstLine) {
for (int i = 0; i < firstLine.length(); i++) {
if (firstLine.charAt(i) != 'X' && firstLine.charAt(i) != 'O')
return false;
}
return true;
}
}
[/code]

Ausgabe:
Zwischenstatus:
XOXOXOXOXXOOXXOOXXOO
Zeichen/Zeile: 4 Anzahl Zeilen: 5
falsetruefalsetruefalsetruefalsetruefalsefalsetruetruefalsefalsetruetruefalsefalsetruetrue

Sieht korrekt aus, ist es aber nicht. Ich glaube, das 2d boolean Array immer nur zu überschreiben, wenn ich nach einzelnen Array-Inhalten (z.B. hallo[1][1]) frage, haben alle den Wert true.

Kannst du mir dabei noch einmal behilflich sein? :)
 

SilverClaw

Aktives Mitglied
Wie ihr es euch alle immer kompliziert machen müsst. o.o

Java:
int line = -1;
boolean [][] alive = new boolean[width][height]; // ist standardmäßig mit false-Werten gefüllt
for(int pos = 0; pos < builder.length(); pos++) {
	if(pos % width == 0) line++; //fängt bei 0 an und zählt alle y-Koordinaten durch
		if(builder.charAt(pos) == 'O') alive[pos % width][line] = true; //setzt lebendig, wenn O
	}
}

Und ab jetzt musst du immer nur if(alive[x-Koordinate][y-Koordinate]) benutzen, um weiter zu rechnen.
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
L Conways Game of Life Java Basics - Anfänger-Themen 4
C Conways Game of Life / "Waldbrandsimulation": wieso temporäres Hilfs-Array?! Java Basics - Anfänger-Themen 8
J Welt in GameOfLife klonen Java Basics - Anfänger-Themen 9
P GameofLife Java Basics - Anfänger-Themen 3
A csv Reader für Java? Java Basics - Anfänger-Themen 27
K Warum wird hier nur etwas in eine txt Datei geschrieben und nicht in alle drei (InputStream/OutputStream/Reader/Writer) Java Basics - Anfänger-Themen 1
R CSV Reader läuft nicht richtig an Java Basics - Anfänger-Themen 8
S Input/Output Reader/Writer finden file nicht Java Basics - Anfänger-Themen 3
L Klassen NFC Reader und JavaFx Problem -> threads? Java Basics - Anfänger-Themen 2
A Reader wohin werden Daten gespeichert? Java Basics - Anfänger-Themen 7
Textsurfer Erste Schritte CSV Import Reader Writer Java Basics - Anfänger-Themen 0
A Reader für Benutzereingabe in Eclipse importieren Java Basics - Anfänger-Themen 3
W Reader Java Basics - Anfänger-Themen 9
W Java XML-Reader: Content not allowed in Prolog Java Basics - Anfänger-Themen 7
D Jpg in BufferedImage Reader oder Array ablegen? Java Basics - Anfänger-Themen 5
C FileWriter bzw. Reader fehlerhaft Java Basics - Anfänger-Themen 6
Sogomn Input/Output Reader, Writer und Streams Java Basics - Anfänger-Themen 6
P txt reader Problem Java Basics - Anfänger-Themen 17
L buffered reader produziert zu viele und seltsame zeichen Java Basics - Anfänger-Themen 2
A Interface Reader interface verwenden Java Basics - Anfänger-Themen 4
S Input/Output Reader: "null" wenn While-Ende Java Basics - Anfänger-Themen 5
F Reader - brauche Hilfe Java Basics - Anfänger-Themen 19
M Reader-Problem Java Basics - Anfänger-Themen 5
Haubitze_Broese RSS-Reader? Java Basics - Anfänger-Themen 2
Haubitze_Broese Pattern für Links in RSS-Reader Java Basics - Anfänger-Themen 6
A Problem Reader Java Basics - Anfänger-Themen 39
Developer_X Sav-Data reader, fehler Java Basics - Anfänger-Themen 2
V Buffered Reader, erst ab bestimmter Zeile auslesen? Java Basics - Anfänger-Themen 8
K Probleme mit Buffered Reader Java Basics - Anfänger-Themen 8
P Buffered Reader an Anfang setzen Java Basics - Anfänger-Themen 4
D RSS Reader mit Redaktionssystem Java Basics - Anfänger-Themen 7
L Streams und Reader/Writer Java Basics - Anfänger-Themen 8
F Was gibt der Buffered Reader zurück bei Dateiende? Java Basics - Anfänger-Themen 2
T Writer/Reader Problem Java Basics - Anfänger-Themen 4
H Buffered Reader Java Basics - Anfänger-Themen 7
G Buffered REader, String, ist mein code korrekt? Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben