[gelöst]Schiffe versenken
-
Hey Leute, hab mich jetzt mal am Schiffe versenken geübt,
aber es funktioniert nicht so richtig.
Und zwar funktioniert das Programm wenn ich z.b. nur 1 2er schiff mach ein dreier schiff und kein 4er schiff.
mach ich aber mehr schiffe z.b. ein vierer, dann passiert einfach gar nix mehr und das programm bleibt stehen, mach ich noch mehr schiffe, kommt ein fehler und das programm wird beendet.
vermut mal dass es vll über mein array hinausschreibt, aber ich habe dies eg abgesichert dass es nicht passieren kann.
ich hab mal den langen quellcode gepostet
hoff er ist nicht zu lange und ihr könnt euch durchlesen, falls nicht kann ich gerne auch noch kommentare einfügen, wollt ich eh machen aber wollt erst mal den fehler suchen und dass probier ich schon seit fast 2 stunden 
main.cpp
#include "classBretter.h" #include <iostream> #include <iomanip> #include <string> using namespace std; void anzahlZweierSchiffe(Bretter&, const int&, const int&); void anzahlDreierSchiffe(Bretter&, const int&, const int&); void anzahlViererSchiffe(Bretter&, const int&, const int&); const int size1 = 10; const int size2 = 10; const int size3 = 4; bool stop = false; int main() { cout << setw(60) << "Herzlich Willkommen bei Schiffeversenken\n"; cout << "\n"; cout << "\n"; cout << setw(61) << "Ein '.' bedeutet noch nicht hingeschossen\n"; cout << setw(56) << "Ein 'X' bedeutet das war nur Wasser\n"; cout << setw(79) << "Ein 'S' bedeutet da ist ein Schiff, die Klammer sagt wie lang das Schiff ist\n"; cout << "\n\n"; Bretter Brett1(size1,size2,size3); anzahlZweierSchiffe(Brett1, size1, size2); anzahlDreierSchiffe(Brett1, size1, size2); anzahlViererSchiffe(Brett1, size1, size2); Brett1.brettAusgeben(size1, size2); int x; int y; while(stop == false) { cout << "\n"; cout << "Wo moechtest du hinschiessen: x= "; cin >> x; cout << "\n"; cout << "Wo moechtest du hinschiessen: y= "; cin >> y; cout << "\n"; Brett1.check(x,y); Brett1.brettAusgeben(size1, size2); } }funktionen.cpp
#include "classBretter.h" #include <iostream> #include <iomanip> using namespace std; void anzahlZweierSchiffe(Bretter& Brett1, const int& size1, const int& size2) { marke:; cout << "Wie viel zweier Schiffe moechtest du(mindestens 1, maximal 3)"; int choice; cin >> choice; if ((choice < 4) && (choice > 0)) { for(int i = 0; i < choice; i++) { Brett1.zweierSchiffeSetzen(size1, size2); } } else { cout << "Falsche Eingabe!\n"; goto marke; } } void anzahlDreierSchiffe(Bretter& Brett1, const int& size1, const int& size2) { marke:; cout << "Wie viel dreier Schiffe moechtest du(mindestens 1, maximal 3)"; int choice; cin >> choice; if ((choice < 4) && (choice > 0)) { for(int i = 0; i < choice; i++) { Brett1.dreierSchiffeSetzen(size1, size2); } } else { cout << "Falsche Eingabe!\n"; goto marke; } } void anzahlViererSchiffe(Bretter& Brett1, const int& size1, const int& size2) { marke:; cout << "Wie viel vierer Schiffe moechtest du(maximal 3)"; int choice; cin >> choice; cout << "\n\n"; if ((choice < 4) && (choice > 0)) { for(int i = 0; i < choice; i++) { Brett1.viererSchiffeSetzen(size1, size2); } cout << setw(58) << "Dann kann es ja losgehen!\n"; } else if (choice == 0) { cout << setw(58) << "Dann kann es ja losgehen!\n"; } else { cout << "Falsche Eingabe!\n"; goto marke; } }classBretter.h
#include <string> #ifndef CLASSBRETTER_H_INCLUDED #define CLASSBRETTER_H_INCLUDED class Bretter { public: Bretter(const int, const int, const int); ~Bretter(){}; void brettAusgeben(const int&, const int&)const; void zweierSchiffeSetzen(const int, const int); void dreierSchiffeSetzen(const int, const int); void viererSchiffeSetzen(const int, const int); void check(int&, int&); private: std::string Brett[10][10][4]; }; #endif // CLASSBRETTER_H_INCLUDEDclassBretter.cpp
#include "classBretter.h" #include <iostream> #include <iomanip> #include <string> using namespace std; Bretter::Bretter(const int size1, const int size2, const int size3) { for (int i = 0; i < size1; i++) { for (int j = 0; j < size2; j++) { Brett[i][j][0] = ". "; } } for (int i = 0; i < size1; i++) { for (int j = 0; j < size2; j++) { Brett[i][j][1] = "0"; } } for (int i = 0; i < size1; i++) { for (int j = 0; j < size2; j++) { Brett[i][j][2] = "0"; } } for (int i = 0; i < size1; i++) { for (int j = 0; j < size2; j++) { Brett[i][j][3] = "0"; } } } void Bretter::brettAusgeben(const int& size1, const int& size2)const { cout << setw(67) << " 0 1 2 3 4 5 6 7 8 9\n"; for (int i = 0; i < size1; i++) { for (int j = 0; j < size2; j++) { if(j == 0) { cout << setw(19) << i << " "; } cout << Brett[i][j][0]; } cout<<"\n"; } } void Bretter::zweierSchiffeSetzen(const int size1, const int size2) { srand((unsigned)time(NULL)); marke:; unsigned int x = rand() % size1; unsigned int y = rand() % size2; if(x+1 > 8) { goto marke; } if ((Brett[y][x][2] == "0") && (Brett[y][x+1][2] == "0")) { if(x+1 > 7) { goto marke; } for (int i = 0; i < 2; i++) { Brett[y][x][2] = "1"; x++; } for (int i = 0;i < 2; i++) { Brett[y][x][3] = "2"; x++; } } else { goto marke; } } void Bretter::dreierSchiffeSetzen(const int size1, const int size2) { srand((unsigned)time(NULL)); marke:; unsigned int x = rand() % size1; unsigned int y = rand() % size2; if (y+2 > 7) { goto marke; } if ((Brett[y][x][2] == "0") && (Brett[y+1][x][2] == "0") && (Brett[y+2][x][2] == "0")) { for (int i = 0; i < 3; i++) { Brett[y][x][2] = "1"; y++; } for (int i = 0;i < 3; i++) { Brett[y][x][3] = "3"; y++; } } else { goto marke; } } void Bretter::viererSchiffeSetzen(const int size1, const int size2) { srand((unsigned)time(NULL)); marke:; unsigned int x = rand() % size1; unsigned int y = rand() % size2; if(y+3 > 7) { goto marke; } if((Brett[y][x][2] == "0") && (Brett[y+1][x][2] == "0") && (Brett[y+2][x][2] == "0") && (Brett[y+3][x][0] == "0")) { for (int i = 0; i < 4; i++) { Brett[y][x][2] = "1"; y++; } for (int i = 0;i < 4; i++) { Brett[y][x][3] = "4"; y++; } } else { goto marke; } } void Bretter::check(int& x, int& y) { if(Brett[y][x][1] == "0") { if(Brett[y][x][2] == "1") { if(Brett[y][x][3] == "2") { cout << "Treffer\n"; Brett[y][x][0] = "S(2) "; Brett[y][x][1] = "1"; } else if(Brett[y][x][3] == "3") { cout << "Treffer\n"; Brett[y][x][0] = "S(3) "; Brett[y][x][1] = "1"; } else if(Brett[y][x][3] == "4") { cout << "Treffer\n"; Brett[y][x][0] = "S(4) "; Brett[y][x][1] = "1"; } } else { Brett[y][x][0] = "X "; Brett[y][x][1] = "1"; cout << "Leider nur Wasser\n"; } } else { cout << "Dort hast du schonmal hingeschossen\n"; }Danke schonmal=)
-
Gratualtion, du hast dich eben gerade freiwillig dazu gemeldet, zu lernen, wie man einen Debugger benutzt. Erster Schritt: Nach "Debugger" googeln und das Gelernte anwenden. Wenn man das erstmal kann, sind solche Fehler ruckzuck gefunden.
-
ok danke, werd mal googlen und schaun ob ich was find, werd mich dann nochmal melden;-)
-
fr33g schrieb:
ich hab mal den langen quellcode gepostet
hoff er ist nicht zu lange und ihr könnt euch durchlesen,Falsch gehofft. Du wusstest doch von Anfang an, dass niemand Lust hat, sich in einen Riesencode von anderen Leuten einzulesen, um deren Fehler zu suchen. Das ist schon deine Sache. Das Forum ist eher da, um konkrete Fragen zu Verständnisproblemen bei C++ zu klären.
fr33g schrieb:
falls nicht kann ich gerne auch noch kommentare einfügen
Nein. Falls nicht, bleibt es an dir hängen.

Aber ich kann dir ein paar Tipps geben. Erstens ist der Debugger, wie SeppJ sagt, eines der wichtigsten Werkzeuge eines Programmierers. Je eher du lernst, mit ihm umzugehen, desto besser. Damit kannst du schrittweise die Variablenwerte deines Programms anschauen und Änderungen nachverfolgen.
Zweitens: Benutze kein
goto. Wenn du dich nicht gut mit der Sprache auskennst, istgotoein heimtükisches, hinterhältiges Sprachmittel. Durch Schleifen und Funktionen ist es in 99% der Fälle unnötig (glaub nicht, dass du zu dem einen Prozent gehörst).Drittens: Array-Indizes sind immer heikel. Da würde ich beim Fehlersuchen besondere Acht drauf legen. Es kann sich extrem lohnen, einen Wrapper wie
std::tr1::arraystatt rohen Arrays zu verwenden, weil diese Klasse im Debug-Modus Indexprüfungen mit sich bringt.
-
fr33g schrieb:
if(y+3 > 7) { goto marke; } if((Brett[y][x][2] == "0") && (Brett[y+1][x][2] == "0") && (Brett[y+2][x][2] == "0") && (Brett[y+3][x][0] == "0")) { for (int i = 0; i < 4; i++) { ... y++; } for (int i = 0;i < 4; i++) { ... y++; } }Zähle mal nach, wie oft y hier inkrementiert wird. Ständiges srand ist nicht zweckmäßig. goto hilft nicht, den Programmablauf zu erfassen. Zudem ist es sinnvoll zu versuchen, die Erzeugung der Zufallspositionen gleich richtig einzuschänken.
void Bretter::viererSchiffeSetzen(const int size1, const int size2) { for ( ;; ) { unsigned int x = rand() % size1; unsigned int y = rand() % ( size2 - 4 + 1 ); if( (Brett[y+0][x][2] == "0") && (Brett[y+1][x][2] == "0") && (Brett[y+2][x][2] == "0") && (Brett[y+3][x][0] == "0")) { for (int i = 0; i < 4; i++) { Brett[y+i][x][2] = "1"; Brett[y+i][x][3] = "4"; } return; } } }Hier scheint sich ein C&P-Fehler eingeschlichen zu haben, der bei ein bisschen Aufmerksamkeit für Formatierung ins Auge sticht.
-
danke erst mal für die tipps, bin grad noch am googlen wie das mit dem debugger so funzt, es hat net jemand einen guten link grad da?
-
fr33g schrieb:
danke erst mal für die tipps, bin grad noch am googlen wie das mit dem debugger so funzt, es hat net jemand einen guten link grad da?
Oftmals arbeiten Debugger eng mit Entwicklungsumgebung und Compiler zusammen. Welche benutzt du?
-
ich benutze code blocks und den gnu compiler.
hoffe ihr könnt mir bissel helfen so dass ich das lernen kann mit dem debuggen=)
-
hast du deine frage schon mal google gestellt?
-
ja das habe ich, wollt aber halt auch nochmal hier fragen falls jemand eh nen guten link hat oder es mir gerne auch noch mal erklärt=)
ist ja wohl nicht verboten...
EDIT:
Also hab mal oben die Fehler weggemacht so weit ich sie hoffentlich erkannt habe.
Mein Problem ist jetzt aber immer noch dass ich nichts gescheites beim goggeln find wegen dem debuggen, da steht immer was von wegen befehle irgendwo eingeben...aber des muss doch auch übers menü gehen, aber der hält bei mir net wirklich bei breakpoints und anzeigen tut er au nix variablen werte oder so:(
-
camper schrieb:
fr33g schrieb:
if(y+3 > 7) { goto marke; } if((Brett[y][x][2] == "0") && (Brett[y+1][x][2] == "0") && (Brett[y+2][x][2] == "0") && (Brett[y+3][x][0] == "0")) { for (int i = 0; i < 4; i++) { ... y++; } for (int i = 0;i < 4; i++) { ... y++; } }Zähle mal nach, wie oft y hier inkrementiert wird. Ständiges srand ist nicht zweckmäßig. goto hilft nicht, den Programmablauf zu erfassen. Zudem ist es sinnvoll zu versuchen, die Erzeugung der Zufallspositionen gleich richtig einzuschänken.
void Bretter::viererSchiffeSetzen(const int size1, const int size2) { for ( ;; ) { unsigned int x = rand() % size1; unsigned int y = rand() % ( size2 - 4 + 1 ); if( (Brett[y+0][x][2] == "0") && (Brett[y+1][x][2] == "0") && (Brett[y+2][x][2] == "0") && (Brett[y+3][x][0] == "0")) { for (int i = 0; i < 4; i++) { Brett[y+i][x][2] = "1"; Brett[y+i][x][3] = "4"; } return; } } }Hier scheint sich ein C&P-Fehler eingeschlichen zu haben, der bei ein bisschen Aufmerksamkeit für Formatierung ins Auge sticht.
Also mein Programm läuft leider immer noch nicht.
hab mir hier nochmal alles durchgelesen, hab jetzt srand nur noch einmal drin und goto auch weg=)
und deine tipps auch umgesetzt.
blos ich raff des net mit y inkrementieren...ich inkrementiere es doch 4 mal oder? so soll es doch auch sein oder was meinst du?
y, y+1 y+2 y+3 y+4, wobei ja das y+4 dann nicht mehr verwendet wird, daher sind es doch 4 felder oder?danke schonmal
EDIT:
Danke an alle die mir tipss gegeben haben, habs hinbekommen warn problem mit dem inkrementieren wie ein vorredner schon sagte, dadurch hab ich über das array hinausgeschrieben:D
Das mit dem debuggen check ich zwar no net so wirklich weil trotz einstellungen hält mein debugger nie an an breakpoints...=(