Schiffe versenken bricht bei mehrfacher Eingabe ab :(
-
Hallo die Herrschaften

Ich habe mich gestern mit meinem bereits "geballten" Wissen über C++ mal ans Werk gemacht und wollte ein einfach-gestaltetes "Schiffe-versenken" programmieren.
Das Spiel an sich läuft jetzt nur habe ich leider noch ein größeres Problem, wo meine "Kenntnisse" sofort ins Leere fallen.und zwar:
Wenn ich im Spiel eine Eingabe der Koordinaten mache,dann funktioniert alles einwandfrei. Jedoch bricht er irgendwann die Eingabeaufforderung ab,wenn man ca. 10-15 Koordinaten getippt hat.
Quelltext:
//-------------Schiffe Versenken-------------// #include <iostream> #include <iomanip> #include <time.h> using namespace std; const int X = 9; // Breite der X-Achse const int Y = 9; // Breite der Y-Achse void Bildschirm(); // Ausgabe Der Spielfelder void Spielfeld_Mensch(); // Spielfeld von Mensch wird erstellt und Schiffe werden gesetzt void Spielfeld_CPU(); // Spielfeld von Computer wird erstellt und Schiffe werden gesetzt void Eingabe_Mensch(); void Eingabe_CPU(); // Eingabe der getippten Koordinaten von Mensch void Auswertung(); // Spielauswertung char Feld_Mensch[X][Y] = {0}; // Anzeige des Spielfeldes von Mensch int Schiffe_Mensch = 5; // Anzahl der Schiffe von Mensch char Feld_CPU[X][Y] = {0}; // Anzeige des Spielfeldes von Mensch char versteckte_Schiffe_CPU[X][Y] = {0}; // Feld für die versteckten Schiffe des Gegners int Schiffe_CPU = 5; // Anzahl der Schiffe des Gegners // HAUPTFUNKTION // int main(void) { int Auswahl = 0; // Variable für die Menueauswahl int i = 0, j = 0; // Zaehlervariablen für Schleifen system("cls"); cout << " #####################" << endl; cout << " # Schiffe Versenken #" << endl; cout << " #####################" << endl << endl; for (i = 0; i < 6; i++) { cout << endl; } for (i = 0; i < X; i++) // Den 3 verschiedenen Feldern werden die Startzeichen eingelesen { for (j = 0; j < Y; j++) { Feld_Mensch[i][j] = '.'; Feld_CPU[i][j] = '.'; versteckte_Schiffe_CPU[i][j] = '0'; } } cout << "Bitte w" << char(132) << "hlen Sie:" << endl; cout << "1 - Neues Spiel" << endl; cout << "2 - Programm verlassen" << endl; cin >> Auswahl; switch(Auswahl) // Auswahl im Menue { case 1: Spielfeld_Mensch(); break; case 2: break; } } // Funktion - Einlesen der Schiffs-Koordinaten von Mensch // void Spielfeld_Mensch() { char cx, cy; // Char-Variablen zum koordinieren der Schiffe int j = 0, k = 0; // Zaehler-Variablen für Schleifen while (Schiffe_Mensch) { system("cls"); int xin = 0, yin = 0; // Int-Variablen zum Verarbeiten der Koordinaten cout << " 1 2 3 4 5 6 7 8 9" << endl; // Ausgabe des Spielfeldes von Mensch for (j = 0; j < X; j++) { cout << " " << char('A' + j); for (k = 0; k < Y; k++) { cout << " " << Feld_Mensch[j][k]; } cout << endl; } cout << endl << "Es sind noch " << Schiffe_Mensch << " Schiffe zu setzen!" << endl; cout << "Wo m" << char(148) << "chten Sie das " << Schiffe_Mensch << ". Schiff hinsetzen?:" << endl; cin >> cx >> cy;fflush(stdin); // Char-Variablen für Koordinaten werden eingelesen xin = cx - '1'; // Umwandlung des Char-Zeichens für X-Achse in Int-Nummer yin = toupper(cy) - toupper('A'); // Umwandlung des Char-Zeichens für Y-Achse in Int-Nummer // Ueberprüfen, dass keine Eingabe doppelt ist if (xin >= 0 && xin < 9 && yin >= 0 && yin < 9 && Feld_Mensch[yin][xin] != char(219)) { Feld_Mensch[yin][xin] = char(219); // Schiff wird gesetzt Schiffe_Mensch--; // Schiffanzahl wird dekrementiert } } Schiffe_Mensch = 5; Spielfeld_CPU(); // Funktion des Spielfeldes des Gegners } // Funktion zum Einlesen der Schiffe des Gegners // void Spielfeld_CPU() { int i = 0; // Zaehler-Variable für Schleife int xin = 0, yin = 0; // Koordinaten der Schiffe des Gegners srand(static_cast<int>(time(NULL))); // Zufallsgenerator for (i = 0; i < Schiffe_CPU;) { xin = rand() % 9; // zufaellige X-Koordinate yin = rand() % 9; // zufaellige Y-Koordinate // Verhindert doppelte Eingaben if (versteckte_Schiffe_CPU[xin][yin] != '1') { versteckte_Schiffe_CPU[xin][yin] = '1'; i++; } } Bildschirm(); } // Funktion zur Anzeige der Spielfelder und der Spieler // void Bildschirm() { int i = 0, j = 0; system("cls"); cout << endl << endl; cout << " **********************" << " " << " **********************" << endl; cout << " *Spielfeld - Player 1*" << " " << " *Spielfeld - Computer*" << endl; cout << " **********************" << " " << " **********************" << endl << endl; cout << " 1 2 3 4 5 6 7 8 9" << " " << " 1 2 3 4 5 6 7 8 9" << endl; // Ausgeben der beiden Spielfelder for (i = 0; i < Y; i++) { cout << " " << char('A' + i); for (j = 0; j < X; j++) { cout << " " << Feld_Mensch[i][j]; } cout << " "; cout << " " << char('A' + i); for (j = 0; j < X; j++) { cout << " " << Feld_CPU[i][j]; } cout << endl; } cout << endl; // Ausgeben der noch versteckten Schiffe cout << " versteckte Schiffe: " << Schiffe_Mensch << " "; cout << " versteckte Schiffe: " << Schiffe_CPU << endl; Eingabe_Mensch(); } // Eingabe der zu Koordinaten von gegnerischen Schiffen // void Eingabe_Mensch() { char cx, cy; // Char-Variablen zum koordinieren der Schiffe int xin = 0, yin = 0; // Zaehler-Variablen für Schleifen cout << "Eingabe: "; cin >> cx; // Einlesen der X-Koordinate cin >> cy; // Einlesen der Y-Koordinate xin = cx - '1'; // Umwandeln der Zeichen in Nummern yin = toupper(cy) - toupper('A'); // Umwandeln der Zeichen in Nummern // Gegner getroffen if (versteckte_Schiffe_CPU[yin][xin] == '1') { versteckte_Schiffe_CPU[yin][xin] = char(15); Feld_CPU[yin][xin] = char(15); cout << endl << "! Sie haben den Feind erwischt !" << endl; Schiffe_CPU--; system("pause"); Eingabe_CPU(); } // vorbei geschossen if (versteckte_Schiffe_CPU[yin][xin] == '0') { versteckte_Schiffe_CPU[yin][xin] = '-'; Feld_CPU[yin][xin] = '-'; cout << endl << "# Sie haben daneben geschossen #" << endl; system("pause"); Eingabe_CPU(); } } // Funktion der "Computer-KI" // void Eingabe_CPU() { int xin = 0, yin = 0; // Koordinaten der Schiffe des Gegners bool gleiche_Koordinaten = true; // Prüf-Variable, ob Koordinaten schon einmal ausgegeben wurden srand(static_cast<int>(time(NULL))); // Zufallsgenerator // Verhindert doppelte Eingaben do { xin = rand() % 9; // zufaellige X-Koordinate yin = rand() % 9; // zufaellige Y-Koordinate // gleiche Koordinaten ausgewürfelt if (Feld_Mensch[yin][xin] == char(15) || Feld_Mensch[yin][xin] == '-') { gleiche_Koordinaten = false; } } while(!gleiche_Koordinaten); // Mensch wurde getroffen if (Feld_Mensch[yin][xin] == char(219)) { Feld_Mensch[yin][xin] = char(15); cout << endl << "! Der Feind hat dich getroffen !" << endl; Schiffe_Mensch--; system("pause"); Bildschirm(); } // Gegner hat daneben geschossen if (Feld_Mensch[yin][xin] == '.') { Feld_Mensch[yin][xin] = '-'; cout << endl << "# Der Feind schiest daneben #" << endl; system("pause"); Bildschirm(); } }ich hoffe ist nicht zuviel.
Da ich noch ziemlich Ahnungslos bin,bitte nicht hauen
Danke schonmal für AntwortenGruß tridane
-
Gegenfrage: Wann sollte dann das Programm beendet werden?
Zum Problem: Ich vermute, das Problem liegt darin, dass sich die Funktionen Bildschirm(), Eingabe_Mensch() und Eingabe_CPU() ständig gegenseitig aufrufen - noch bevor sie wirklich beendet sind.
Zur Struktur: Du hast quasi ein lineares Programm geschrieben, und der Übersichtlichkeit halber in einzelne Programme aufgeteilt. Positiv: Du hast sehr sehr viele Details beachtet, und ausserdem gut kommentiert. Aber den Grundaufbau solltest du nochmals überdenken.
"Was soll geschehen, unter welcher Bedingung, in welcher Reihenfolge?" - Diese Frage sollte beantwortet werden, wenn man die main() bzw. doGame() oder whatever durchliest.
Tipps:
- Funktionen grundsätzlich von main() aus aufrufen
- Nicht "linear" programmieren -> die Funktionen rufen sich nicht gegenseitig auf
- Abbruchbedingung definieren (Schleifen)
- Argumente verwenden, z.b. isGetroffen(int xin, int yin);
- Rückgabewert weiterverwenden, z.b. if (isGetroffen(..))
- Globale Variabeln vermeiden (ausser vielleicht X, Y)
-
soooooooo...
erstmal Danke für deine Antwort

Da ich heute nun endlich mal wieder Zeit hatte, hab ich mich gleich über das Problem hergemacht und weitestgehend versucht deine Tipps zu folgen.
Leider besteht das Problem immernoch.Der überarbeitete Quelltext sieht nun wiefolgt aus:
//-------------Schiffe Versenken-------------// #include <iostream> #include <iomanip> #include <time.h> using namespace std; // Festlegung der konstanten Variablen // const int X = 9; // Breite der X-Achse const int Y = 9; // Breite der Y-Achse // Festlegung der Prototypen // int Spielfeld_Mensch(int&, char[][Y]); // Spielfeld von Mensch wird erstellt und Schiffe werden gesetzt int Spielfeld_CPU(int&, char[][Y]); // Spielfeld von Computer wird erstellt und Schiffe werden gesetzt int Bildschirm(int&, int&, char[][Y], char[][Y]); // Ausgabe Der Spielfelder int Eingabe_Mensch(int&, char[][Y], char[][Y]); // Eingabe der getippten Koordinaten von Mensch int Eingabe_CPU(int&, char[][Y]); // Eingabe der getippten Koordinaten von der CPU void Auswertung(); // Spielauswertung // HAUPTFUNKTION // int main(void) { int Auswahl = 0; // Variable für die Menueauswahl int i = 0, j = 0; // Zaehlervariablen für Schleifen char Feld_Mensch[X][Y] = {0}; // Anzeige des Spielfeldes von Mensch int Schiffe_Mensch = 5; // Anzahl der Schiffe von Mensch char Feld_CPU[X][Y] = {0}; // Anzeige des Spielfeldes von CPU char versteckte_Schiffe_CPU[X][Y] = {0}; // Feld für die versteckten Schiffe des Gegners int Schiffe_CPU = 5; // Anzahl der Schiffe des Gegners system("cls"); cout << " #####################" << endl; cout << " # Schiffe Versenken #" << endl; cout << " #####################" << endl << endl; for (i = 0; i < 6; i++) { cout << endl; } for (i = 0; i < X; i++) // Den 3 verschiedenen Feldern werden die Startzeichen eingelesen { for (j = 0; j < Y; j++) { Feld_Mensch[i][j] = '.'; Feld_CPU[i][j] = '.'; versteckte_Schiffe_CPU[i][j] = '0'; } } cout << "Bitte w" << char(132) << "hlen Sie:" << endl; cout << "1 - Neues Spiel" << endl; cout << "2 - Programm verlassen" << endl; cin >> Auswahl; switch(Auswahl) // Auswahl im Menue { case 1: Spielfeld_Mensch(Schiffe_Mensch, Feld_Mensch); // Funktion zum Setzen der Schiffe Mensch Spielfeld_CPU(Schiffe_CPU, versteckte_Schiffe_CPU); // Funktion zum Setzen der Schiffe CPU // Schleife wird solang wiederholt, bis bei einem der Spieler alle Schiffe gefunden wurden // while (Schiffe_Mensch > 0 || Schiffe_CPU > 0) { Bildschirm(Schiffe_Mensch, Schiffe_CPU, Feld_Mensch, Feld_CPU); // Ausgabe des Spielfeldes Eingabe_Mensch(Schiffe_CPU, versteckte_Schiffe_CPU, Feld_CPU); // Funktion zum Suchen der gegnerischen Schiffe Eingabe_CPU(Schiffe_Mensch, Feld_Mensch); // Funktion für die "CPU - KI" } break; case 2: break; default: main(); break; } return 0; } // Funktion - Einlesen der Schiffs-Koordinaten von Mensch // int Spielfeld_Mensch(int& ref_Schiffe_Mensch, char Feld_Mensch[][Y]) { char cx, cy; // Char-Variablen zum koordinieren der Schiffe int j = 0, k = 0; // Zaehler-Variablen für Schleifen while (ref_Schiffe_Mensch) { system("cls"); int xin = 0, yin = 0; // Int-Variablen zum Verarbeiten der Char-Koordinaten cout << " 1 2 3 4 5 6 7 8 9" << endl; // Ausgabe des Spielfeldes von Mensch for (j = 0; j < X; j++) { cout << " " << char('A' + j); for (k = 0; k < Y; k++) { cout << " " << Feld_Mensch[j][k]; } cout << endl; } cout << endl << "Es sind noch " << ref_Schiffe_Mensch << " Schiffe zu setzen!" << endl; cout << "Wo m" << char(148) << "chten Sie das " << ref_Schiffe_Mensch << ". Schiff hinsetzen?:" << endl; cin >> cx >> cy; // Char-Variablen für Koordinaten werden eingelesen xin = cx - '1'; // Umwandlung des Char-Zeichens für X-Achse in Int-Nummer yin = toupper(cy) - toupper('A'); // Umwandlung des Char-Zeichens für Y-Achse in Int-Nummer // Ueberprüfen, dass keine Eingabe doppelt ist if (xin >= 0 && xin < 9 && yin >= 0 && yin < 9 && Feld_Mensch[yin][xin] != char(219)) { Feld_Mensch[yin][xin] = char(219); // Schiff wird gesetzt ref_Schiffe_Mensch--; // Schiffanzahl wird dekrementiert } } ref_Schiffe_Mensch = 5; // Schiffanzahl wird wieder auf 5 zurückgesetzt return (ref_Schiffe_Mensch, Feld_Mensch[X][Y]); } // Funktion zum Einlesen der Schiffe des Gegners // int Spielfeld_CPU(int& ref_Schiffe_CPU, char versteckte_Schiffe_CPU[][Y]) { int i = 0; // Zaehler-Variable für Schleife int xin = 0, yin = 0; // Koordinaten der Schiffe des Gegners srand(static_cast<int>(time(NULL))); // Zufallsgenerator for (i = 0; i < ref_Schiffe_CPU;) { xin = rand() % 9; // zufaellige X-Koordinate yin = rand() % 9; // zufaellige Y-Koordinate // Verhindert doppelte Eingaben if (versteckte_Schiffe_CPU[xin][yin] != '1') { versteckte_Schiffe_CPU[xin][yin] = '1'; i++; } } return (ref_Schiffe_CPU, versteckte_Schiffe_CPU[X][Y]); } // Funktion zur Anzeige der Spielfelder und der Spieler // int Bildschirm(int& ref_Schiffe_Mensch, int& ref_Schiffe_CPU, char Feld_Mensch[][Y], char Feld_CPU[][Y]) { int i = 0, j = 0; system("cls"); cout << endl << endl; cout << " **********************" << " " << " **********************" << endl; cout << " *Spielfeld - Player 1*" << " " << " *Spielfeld - Computer*" << endl; cout << " **********************" << " " << " **********************" << endl << endl; cout << " 1 2 3 4 5 6 7 8 9" << " " << " 1 2 3 4 5 6 7 8 9" << endl; // Ausgeben der beiden Spielfelder for (i = 0; i < Y; i++) { cout << " " << char('A' + i); for (j = 0; j < X; j++) { cout << " " << Feld_Mensch[i][j]; } cout << " "; cout << " " << char('A' + i); for (j = 0; j < X; j++) { cout << " " << Feld_CPU[i][j]; } cout << endl; } cout << endl; // Ausgeben der noch versteckten Schiffe cout << " versteckte Schiffe: " << ref_Schiffe_Mensch << " "; cout << " versteckte Schiffe: " << ref_Schiffe_CPU << endl; return (ref_Schiffe_Mensch, ref_Schiffe_CPU, Feld_Mensch[X][Y], Feld_Mensch[X][Y]); } // Eingabe der zu Koordinaten von gegnerischen Schiffen // int Eingabe_Mensch(int& ref_Schiffe_CPU, char versteckte_Schiffe_CPU[][Y], char Feld_CPU[][Y]) { char cx, cy; // Char-Variablen zum koordinieren der Schiffe int xin = 0, yin = 0; // Zaehler-Variablen für Schleifen cout << "Eingabe: "; cin >> cx; // Einlesen der X-Koordinate cin >> cy; // Einlesen der Y-Koordinate xin = cx - '1'; // Umwandeln der Zeichen in Nummern yin = toupper(cy) - toupper('A'); // Umwandeln der Zeichen in Nummern // Gegner getroffen if (versteckte_Schiffe_CPU[yin][xin] == '1') { versteckte_Schiffe_CPU[yin][xin] = char(15); Feld_CPU[yin][xin] = char(15); cout << endl << "! Sie haben den Feind erwischt !" << endl; ref_Schiffe_CPU--; system("pause"); } // vorbei geschossen if (versteckte_Schiffe_CPU[yin][xin] == '0') { versteckte_Schiffe_CPU[yin][xin] = '-'; Feld_CPU[yin][xin] = '-'; cout << endl << "# Sie haben daneben geschossen #" << endl; system("pause"); } return (ref_Schiffe_CPU, versteckte_Schiffe_CPU[X][Y], Feld_CPU[X][Y]); } // Funktion der "Computer-KI" // int Eingabe_CPU(int& ref_Schiffe_Mensch, char Feld_Mensch[][Y]) { int xin = 0, yin = 0; // Koordinaten der Schiffe des Gegners bool gleiche_Koordinaten = true; // Prüf-Variable, ob Koordinaten schon einmal ausgegeben wurden srand(static_cast<int>(time(NULL))); // Zufallsgenerator // Verhindert doppelte Eingaben do { xin = rand() % 9; // zufaellige X-Koordinate yin = rand() % 9; // zufaellige Y-Koordinate // gleiche Koordinaten ausgewürfelt if (Feld_Mensch[yin][xin] == char(15) || Feld_Mensch[yin][xin] == '-') { gleiche_Koordinaten = false; } } while(!gleiche_Koordinaten); // Mensch wurde getroffen if (Feld_Mensch[yin][xin] == char(219)) { Feld_Mensch[yin][xin] = char(15); cout << endl << "! Der Feind hat dich getroffen !" << endl; ref_Schiffe_Mensch--; system("pause"); } // Gegner hat daneben geschossen if (Feld_Mensch[yin][xin] == '.') { Feld_Mensch[yin][xin] = '-'; cout << endl << "# Der Feind schiest daneben #" << endl; system("pause"); } return (ref_Schiffe_Mensch, Feld_Mensch[X][Y]); }Das Spiel endet mit der Funktion "Ausgabe". Die hab ich aber einfach noch nicht gemacht,weil das Spiel vorher schon immer wieder abstürzt.
Das gleiche Problem besteht leider immernoch. Es passiert nach ca. 10 Koordinaten-Eingaben einfach nichts mehr.
Ich hatte dasselbe Problem schonmal in einem anderen Programm mit "cin.getline" konnte es aber mit "fflush(stdin)" lösen,was hier leider nicht geht

Außerdem haben sich bei mir noch folgende Fragen gebildet:
1. Warum übergibt man eine 2D-Matrix immer so,dass die Variable in der ersten Klammer weggelassen wird --> Feld_Mensch[???][Y]
2. Wie übergebe ich per Pointer eine 2D-Matrix. Ich hab irgendwie nicht den passenden Thread gefunden und mein selbst ausprobieren wurde ich mit Fehlern überhäuft^^
Danke schonmal

Gruß tridane
-
nur ganz schnell:
http://tutorial.schornboeck.net/referenzen.htm
(referenzierte variablen muss man nicht zurückgeben..)2D-Arrays: such mal nach "mehrdimensionales array"