Problem mit eingelesener Datei
-
Hallo ich bins schon wieder^^
Habe vor mal ein komplexeres "Spiel" zu schreiben. Möchte dies jedoch erstmal in der Konsole tun, um nur die Technik programmieren zu müssen und mich um keine Sprites o.ä. kümmern zu müssen. Stehe jetzt jedoch vor einem "kleinen" Problem.
Habe eine Textdatei (das Level) weclhe einegelesen wird, z.B. sowas:
11111111111111111111111111111111111111111111111111 00000000000000000000000000000000000000000000000001 11111111111111111111111111111111111111111111111101 10000000000000000000000000000000000000000000000001 10111111111111111111111111111111111111111111111111 10100000000000000000000000000000000000000000000001 10100000000000000000000000000000000000000000000001 10100000000000000000000000000000000000000000000001 10111111111111111111111111111111111111111111111111 10000000000000000000000000000000000000000000000001 11111111111111111111111001111111111111111111111111 10000000000000000000001001000000000000000000000001 10000000000000000000001001000000000000000000000001 11111111111111111111111001111111111111111111111111 10000000000000000000000000000000000000000000000001 10111111111111111111111111111111111111111111111101 10100000000000000000000000000000000000000000000101 10100000000000000000000000000000000000000000000101 10100000000000000000000000000000000000000000000101 10100000000000000000000000000000000000000000000101 10100000000000000000000000000000000000000000000101 10100000000000000000000000000000000000000000000101 10111111111111111111111111111111111111111111111101 10000000000000000000000000000000000000000000000001 11111111111111111111111331111111111111111111111111Die Zeichenfolge soll nun in ein dynamisches Array (bewusst erstmal keinen Vektor) namens feldZustand. Das erledigt diese Funktion:
int Spielfeld::getLevel(std::string level) { std::string datei = level + ".txt"; std::ifstream levelDatei(datei.c_str(), std::ios::in); if(!levelDatei) { std::cerr << "Fehler beim Erzeugen des Levels!" << std::endl; std::cin.get(); return -1; } else { for(int i = 0; i < YMAX; i++) { std::string buffer; getline(levelDatei, buffer); for(int j = 0; j < XMAX; j++) { feldZustand[i*j] = buffer[j]; } } } levelDatei.close(); return 0; };Dann habe ich eine Funktion die diese Folge in das eigentliche Level umwandeln soll:
void Spielfeld::aktualisiereFeld() { // aktualisieren bzw. vergleichen for(int i = 0; i < YMAX; i++) { for(int j = 0; j < XMAX; j++) { switch(feldZustand[i*j]) { case KEIN_ZUSTAND: feld[i*j] = LEER; break; case 1: feld[i*j] = MAUER; break; case 2: feld[i*j] = TURM; break; case 3: feld[i*j] = ZIEL; break; } } } };Und schlussendlich noch eine Funktion, die dieses Level zeichnen soll.
void Spielfeld::zeichneSpielfeld() { // altes Feld (visuell) löschen system("cls"); // zeichnen for(int i = 0; i < YMAX; i++) { for(int j = 0; j < XMAX; j++) { std::cout << feld[i*j]; } std::cout << std::endl; } };Das Problem besteht darin, dass aus irgendeinem Grund das Feld/Level nicht gezeichnet wird. Ersetze ich in der zeichnen-Funktion testweise "std::cout << feld[i*j];" durch "std::cout << 'X';", wird immerhin das ausgegeben. Ich vermute, dass der Fehler in einer der beiden ersten FUnktionen oder beim Einlesen der Datei liegt.
Vielleicht hat einer von euch ja eine Idee.
MfG
ChromaP.S. Kritik an meinem Programmierstil nehme ich natürlich auch gerne an, da dieser mit sehr hoher Wahrscheinlichkeit schlecht oder ausbaufähig ist.

-
Geh doch einfach mit dem Debugger durch den Code und schau, an welcher Stelle was schief geht.
-
hab ich schon, aber es geht ja im eigentlichen sinne nichts "schief", also er zeigt mir keinen Fehler an.
-
Dein Programm arbeitet nicht wie es soll. Also müssen an irgend einer Stelle in Variablen falsche Werte stehen (oder du einfach einen Denkfehler im Datenfluss haben).
Hab deinen Code nur überflogen, aber der Zugreif auf dein Array scheint mir falsch zu sein.
feldZustand[i*j]Du gibst nirgends an, was feldZustand exakt ist, aber ich tippe mal auf ein 1dim Array, das ein 2dim Array darstellen soll (sprich ein linearisiertes 2D array).
Wenn dem so ist, sollte der Zugriff eher so aussehen:feldZustand[i * YDIM + j]
-
ja, es ist ein 1Dmin-Array
int *feldZustand; char *feld;feldZustand = new int[XMAX*YMAX]; feld = new char[XMAX*YMAX];habe die aufrufe jetzt korrigiert.
Das Problem besteht jedoch weiterhin.
-
Du liest dein Array 'feldZustand' doch als 'char's ein, d.h. dort drin stehen die Werte '0', '1' etc. und nicht 0, 1, etc.
Ändere daher mal die case-Werte:
case '1': feld[i*XMAX+j] = MAUER; break; // etc...Ansonsten lerne mit dem Debugger umzugehen -)
-
gut wäre, nach deinen Änderungen den aktuellen Codestand zu liefern, da es nun schwer fällt, zu wissen, was du wirklich geändert hast. aber wie this->that schon meinte:
Chroma schrieb:
for(int i = 0; i < YMAX; i++)
{
std::string buffer;
getline(levelDatei, buffer);
for(int j = 0; j < XMAX; j++)
{
feldZustand[i*j] = buffer[j];
}
}i j Code 0 0 feldZustand[0] = buffer[0]; 0 1 feldZustand[0] = buffer[1]; 0 2 feldZustand[0] = buffer[2];Du überschreibst immer deine Werte
und das quasi überall und anderswo
-
@Th69: feldZustand ist ein int Array
feld ist ein char ArrayHier nochmal der aktuelle Code:
// SPIELFELD - Deklarationen #include <string> #define XMAX 50 #define YMAX 25 #define KEIN_ZUSTAND 0 // 0 = LEER, 1 = MAUER, 2 = TURM, 3 = Zielbereich #define LEER ' ' #define TURM 'Q' #define TEMP_TURM 'T' #define MAUER 'X' #define ZIEL 'Z' // TASTEN #define ENTER 13 #define ESC 27 #define PFEIL_OBEN 72 #define PFEIL_LINKS 75 #define PFEIL_RECHTS 77 #define PFEIL_UNTEN 80 class Spielfeld { private: int groesseX, groesseY; int *feldZustand; char *feld; public: Spielfeld(); ~Spielfeld(); int getLevel(std::string level); void aktualisiereFeld(); void zeichneSpielfeld(); bool setTurm(int eingabe); };// SPIELFELD - Implementationen #include "spielfeld.h" #include <Windows.h> #include <fstream> #include <iostream> #include <conio.h> Spielfeld::Spielfeld() { groesseX = XMAX; groesseY = YMAX; feldZustand = new int[XMAX*YMAX]; feld = new char[XMAX*YMAX]; // initialisieren for(int i = 0; i < YMAX; i++) { for(int j = 0; j < XMAX; j++) { feldZustand[i*YMAX+j] = KEIN_ZUSTAND; } } for(int i = 0; i < YMAX; i++) { for(int j = 0; j < XMAX; j++) { feld[i*YMAX+j] = LEER; } } } Spielfeld::~Spielfeld() { delete[] feldZustand; delete[] feld; }; int Spielfeld::getLevel(std::string level) { std::string datei = level + ".txt"; std::ifstream levelDatei(datei.c_str(), std::ios::in); if(!levelDatei) { std::cerr << "Fehler beim Erzeugen des Levels!" << std::endl; std::cin.get(); return -1; } else { for(int i = 0; i < YMAX; i++) { std::string buffer; getline(levelDatei, buffer); for(int j = 0; j < XMAX; j++) { feldZustand[i*YMAX+j] = buffer[j]; } } } levelDatei.close(); return 0; }; void Spielfeld::aktualisiereFeld() { // aktualisieren bzw. vergleichen for(int i = 0; i < YMAX; i++) { for(int j = 0; j < XMAX; j++) { switch(feldZustand[i*YMAX+j]) { case KEIN_ZUSTAND: feld[i*j] = LEER; break; case 1: feld[i*YMAX+j] = MAUER; break; case 2: feld[i*YMAX+j] = TURM; break; case 3: feld[i*YMAX+j] = ZIEL; break; } } } }; void Spielfeld::zeichneSpielfeld() { // altes Feld (visuell) löschen system("cls"); // zeichnen for(int i = 0; i < YMAX; i++) { for(int j = 0; j < XMAX; j++) { std::cout << feld[i*YMAX+j]; } std::cout << std::endl; } }; bool Spielfeld::setTurm(int eingabe) { // Startpos static int x = 25, y = 12; static char saveZustand = feld[x*x+y]; // Bewegung switch(eingabe) { case PFEIL_OBEN: if(y == 0) { // NICHTS } else { feld[x*YMAX+y] = saveZustand; y--; } break; case PFEIL_LINKS: if(x == 0) { // NICHTS } else { feld[x*YMAX+y] = saveZustand; x--; } break; case PFEIL_RECHTS: if(x == XMAX) { // NICHTS } else { feld[x*YMAX+y] = saveZustand; x++; } break; case PFEIL_UNTEN: if(y == YMAX) { // NICHTS } else { feld[x*YMAX+y] = saveZustand; y++; } break; } if(eingabe == ENTER) { if(feld[x*YMAX+y] == MAUER || feld[x*YMAX+y] == TURM) { std::cerr << "Platzierung nicht moeglich!" << std::endl; return false; } else { feld[x*YMAX+y] = TURM; return true; } } if(eingabe == ESC) { std::cerr << "Platzierung abgebrochen!" << std::endl; feld[x*YMAX+y] = saveZustand; x = 25, y = 12; return true; } saveZustand = feld[x*YMAX+y]; feld[x*YMAX+y] = TEMP_TURM; return false; };Habe jetzt einfach mal den kompletten Code gepostet damit auch ja nichts fehlt

Naja das mit dem Debugger stimmt wohl. Kann in zwar benutzen, aber noch nicht wirklich effektiv. Aber ich bin ja auch noch im Lernprozess^^
EDIT: musste beim posten des Codes grad feststellen, wie sinnlos groesseX und groesseY sind
bitte einfach nicht beachten 
-
Zeile 75: Hier stimmt der Index nicht
Zeile 29: kann auch in die for-Schleife (Zeile 21)Außerdem muss dein Index im ganzen Code von i*YMAX+j auf i*XMAX+j geaendert werden
-
Danke für die Kritik. Habe versucht alles umzusetzen. Das Feld wird leider immer noch nicht angezeigt. Der aktuelle Code ist:
// SPIELFELD - Implementationen #include "spielfeld.h" #include <Windows.h> #include <fstream> #include <iostream> #include <conio.h> Spielfeld::Spielfeld() { feldZustand = new int[XMAX*YMAX]; feld = new char[XMAX*YMAX]; // initialisieren for(int i = 0; i < YMAX; i++) { for(int j = 0; j < XMAX; j++) { feldZustand[i*XMAX+j] = KEIN_ZUSTAND; feld[i*XMAX+j] = LEER; } } } Spielfeld::~Spielfeld() { delete[] feldZustand; delete[] feld; }; int Spielfeld::getLevel(std::string level) { std::string datei = level + ".txt"; std::ifstream levelDatei(datei.c_str(), std::ios::in); if(!levelDatei) { std::cerr << "Fehler beim Erzeugen des Levels!" << std::endl; std::cin.get(); return -1; } else { for(int i = 0; i < YMAX; i++) { char temp; std::string buffer; getline(levelDatei, buffer); for(int j = 0; j < XMAX; j++) { temp = buffer[j]; switch(temp) { case '48': feldZustand[i*XMAX+j] = 0; break; case '49': feldZustand[i*XMAX+j] = 1; break; case '50': feldZustand[i*XMAX+j] = 2; break; case '51': feldZustand[i*XMAX+j] = 3; break; } } } } levelDatei.close(); return 0; }; void Spielfeld::aktualisiereFeld() { // aktualisieren bzw. vergleichen for(int i = 0; i < YMAX; i++) { for(int j = 0; j < XMAX; j++) { switch(feldZustand[i*XMAX+j]) { case KEIN_ZUSTAND: feld[i*XMAX+j] = LEER; break; case 1: feld[i*XMAX+j] = MAUER; break; case 2: feld[i*XMAX+j] = TURM; break; case 3: feld[i*XMAX+j] = ZIEL; break; } } } }; void Spielfeld::zeichneSpielfeld() { // altes Feld (visuell) löschen system("cls"); // zeichnen for(int i = 0; i < YMAX; i++) { for(int j = 0; j < XMAX; j++) { std::cout << feld[i*XMAX+j]; } std::cout << std::endl; } }; bool Spielfeld::setTurm(int eingabe) { // Startpos static int x = 25, y = 12; static char saveZustand = feld[x*x+y]; // Bewegung switch(eingabe) { case PFEIL_OBEN: if(y == 0) { // NICHTS } else { feld[x*XMAX+y] = saveZustand; y--; } break; case PFEIL_LINKS: if(x == 0) { // NICHTS } else { feld[x*XMAX+y] = saveZustand; x--; } break; case PFEIL_RECHTS: if(x == XMAX) { // NICHTS } else { feld[x*XMAX+y] = saveZustand; x++; } break; case PFEIL_UNTEN: if(y == YMAX) { // NICHTS } else { feld[x*XMAX+y] = saveZustand; y++; } break; } if(eingabe == ENTER) { if(feld[x*XMAX+y] == MAUER || feld[x*XMAX+y] == TURM) { std::cerr << "Platzierung nicht moeglich!" << std::endl; return false; } else { feld[x*XMAX+y] = TURM; return true; } } if(eingabe == ESC) { std::cerr << "Platzierung abgebrochen!" << std::endl; feld[x*XMAX+y] = saveZustand; x = 25, y = 12; return true; } saveZustand = feld[x*XMAX+y]; feld[x*XMAX+y] = TEMP_TURM; return false; };