Zweidimensionales Array

Ich habe eine Übungsaufgabe (https://wiki.freitagsrunde.org/Javakurs/Übungsaufgaben/Doom) im Internet gefunden und wollte die Lösen.
Auch alles super, ist ja wirklich eine sehr einfache Aufgabe. ABER ich kriege an einer Stelle große Probleme.

Explizit geht es dabei um die Aufgabe " Das GameField"

Wenn ich in der convert Method mir jedes einzelne Zeichen ausgebe kommt die richtige Ausgabe herraus, aber in der toString methode sind immer leerzeichen etc. dazwischen die dort nicht sein sollten. ( Ich denke das liegt daran das das array “falsch herrum” durchgangen wird)

EDIT: Zwischen den Rauten sind mehrfache Leerzeichen, in der Konsole aus eclipse sichtbar; Hier aber nicht.


convert Ausgabe: #########      ##      ####    ##      #########
falsche Ausgabe: #######  # ##  # ##    ##    ##    ##    #######


import visual.GameField;

public class GameMain {

	public static void main(String[] args) {
		
		String s = "########" +
				  "#      #" +
				  "#      #" +
				  "###    #" +
				  "#      #" +
				  "########";
		
		
		new GameField(s,8);
	}

}

import data.GameTile;

public class GameField {

	private GameTile[][] field;

	private int width;

	public GameField(String ascii, int width) {

		this.width = width;
		this.convertStringInTiles(ascii);

		this.toString();

	}

	@Override
	public String toString() {

		String ascii_field = "";

		for (int i = 0; i < field.length; i++) {
			for (int a = 0; a < field**.length; a++) {
               System.out.print(field**[a]);
			}
			System.out.println("");
		}
		return ascii_field;
	}

	private void convertStringInTiles(String string_field) {
		field = new GameTile[width][string_field.length() / width];

		int counterX = 0;

		int counterY = 0;

		for (char c : string_field.toCharArray()) {

			if (counterX == width) {
				counterY++;
				counterX = 0;
			}

			field[counterX][counterY] = GameTile.getTile(c);
			counterX++;

		}
	}
}
package data;

public class GameTile {

	private Position position;

	public String toString() {
		return " ";
	}

	public static GameTile getTile(char tileChar) {
		if (tileChar == '~')
			return new WaterTile();
		if (tileChar == '#')
			return new WallTile();
		if (tileChar == ' ')
			return new EmptyTile();
		return new EmptyTile();

	}
}

tja, du hast es im Grunde schon erkannt (das array „falsch herum“ durchgangen), aber warum dann nicht weiter durch eigenständiges Denken zum Ziel?
das ist immer die Frage für mich bei solchen Fragen statt nur die Lösung zu nennen :wink:

wichtig wäre genau so ein Problem auch selbstständig lösen zu können,
wichtiger als 100 Programme nach Anleitung korrekt zu programmieren…


die Klasse GameTile hast du zu einem funktionierenden Programm weggelassen,
freilich könnte man das Problem auch so im Code erkennen…

nicht so gut aber aus dem Hinweis

convert Ausgabe: #########      ##      ####    ##      #########
falsche Ausgabe: #######  # ##  # ##    ##    ##    ##    #######

hattest du das ursprünglich mit Zeilenumbrüchen geplant, aber verlorengegangen?..

das Problem ist also, dass die Ausgabe an der Diagonalen gespiegelt ist


ein 2D-Array ist das was es ist,
zwei Dimensionen, wie ein Schachfeld, man kann Daten in/ aus der ersten Zeile schreiben/ lesen, oder aus der 1. Spalte
(oder noch anderes wirres, hier zum Glück nicht)

vielleicht hilft es dir, statt wenig deutlicher und unübersichtlich zahlreichen Raute und Leerzeichen
zunächst ein einfacheres eindeutigeres Spielfeld a la
123
456
789
oder auch nur
12
34
zu testen

wie die Endausgabe sein wird, nicht das gewünschte, das weißt du wohl eh schon, nix neues,
aber vielleicht sind leichter die beiden beteiligten Schritte zu untersuchen:
1.) von String ins Array geschrieben wird (welchen Wert an welche exakte Position), und wie das
2.) vom Array zur Ausgabe gelesen wird

beide Schritte müssen schon zueinanderpassen,
prüfe genau was wohin kommt, welche exakte Array-Darstellung hast du dir vorgestellt, wird sie auch erreicht?

wenn die Array-Darstellung nicht stimmt, kann diese Erstellung bearbeitet werden,
stimmt sie, dann muss der Weg zum String eben so gewählt werden, dass auch der richtiger herauskommt

freilich ist die Prüfung des Arrays nicht ganz simpel, denn das ist es ja, was die Darstellung toString() im Moment auch schon macht…,
da hilft nicht viel, da musst du einfach einige Zeit dran sitzen und möglichst genau drüber nachdenken


so, das war nun durchaus schon Hilfe, aber kommst du ansonsten eigenständig etwas weiter?

zu 1) Wie bereits gesagt die Konvertierung ist korrekt. Das Array hat an den richtigen Stellen auch die richtige Information

zu 2) ```for (int i = 0; i < field[0].length; i++) {
for (int a = 0; a < width; a++) {
System.out.print(field[a]**);
}
System.out.println("");

	}```

Das es jetzt funktioniert ist sehr merkwürdig, da ich die konkreten Zahlen eingegeben hatte und trotzdem ein falsches Ergbeniss hatte. D.h. ich habe was am Code verändert und es selber nicht richtig aufgefasst.

der Code jetzt mit
System.out.print(field[a]**);
ist doch ein anderer als am Anfang
System.out.print(field**[a]);
wieso also ‘merkwürdig, dass es jetzt funktioniert’? wobei du auch nur so nebenher voraussetzt/ kommentierst, dass es bei dir nun funktioniert…

also dann nochmal deutlich angesprochen:
meiner Meinung nach ist convert-Methode falsch, die erste Zeile der String schreibst du in die erste Spalte des Arrays, an die Positionen [0][0], [1][0], [2][0] usw.,
wobei man natürlich immer streiten kann, was Zeile und was Spalte ist

mit quadratischen Arrays ist es eh noch einfacher, teste nochmal 5x3 falls je erlaubt, dann gibt es mehr Probleme wenn nicht genau aufgepasst

5x3 habe ich versucht und hat auch funktioniert.

das mit dem Tausch von a|i hatte ich schon vorher, deswegen “wusste” ich das es ja falsch herrum ist

Wenn ich das in der convert Method ändere dann habe ich doch einfach den Umtausch wieder von i|a.

Dazu kommt das wenn ich Abfrage was an der Stelle [0/1] ist, dann kommt korrekter Weise ‘#’ raus. bei [1/1] dann ’ ’

[quote=Quiji]das mit dem Tausch von a|i hatte ich schon vorher, deswegen “wusste” ich das es ja falsch herrum ist[/quote]Was solche Fehler deutlich erschwehrt ist, wenn mal statt a und i zeilenIndex und spaltenIndex schreibt…

bye
TT

ach, neben [a]** statt **[a] sind ja auch die Schleifenbedingungen getauscht, dann passt im Moment alles zusammen, richtig,

bleibt nur die Frage, wie man es im Array anordnen will,
dabei noch an dieser Stelle als Info angemerkt dass ein 2D-Array ein Array von 1D-Arrays ist

mein Beispiel, bzw. lieber mit Buchstaben und nicht quadratisch
AB
CD
EF
könnte man auf zwei Weisen organisieren:

0,0 = A - 0,1 = B - also ein 1D-Array [A, B] an Position 0 des 2D-Array
1,0 = C - 1,1 = D
2,0 = E - 2,1 = F

oder
0,0 = A - 0,1 = C - 0,2 = E also ein 1D-Array [A, C, E] an Position 0 des 2D-Array
1,0 = B - 1,1 = D - 1,2 = F .

im Moment hast du die zweite Variante,
deswegen bei der Ausgabe der zweite Index i in der äußeren Schleife,
damit „AB“ im String erscheint musst du für i=0 und variablen a 0,0 = A sowie 1,0 = B zusammensammeln,

möglich ist beides, aber natürlicher und verbreiteter dürfte die erste Variante sein,
dann könnte man auch field[0] = ein 1D-Unterarray [A, B] an eine Untermethode übergeben

bei Interesse noch einmal durch den Kopf gehen lassen

noch witziger ist Abspeichern der Daten in einem langen 1D-Array und Berechnung der Indexe,
getGameTile(int x, int y) → field[x*breite+y] oder ähnliches :wink:

So oder so sollte man das kapseln, damit alle diese Fragen von außen nicht relevant sind.