Black Jack Vector out of range



  • Hallo!

    Als Projekt für die Schule soll ich das Kartenspiel Black Jack programmieren.
    Kurz vorm Ende bin ich auf ein Problem gestossen.
    Hier ist erstmal der code (hoffe das reicht, will meinen ganzen code nicht public machen)

    //main.cpp
    #include <iostream>
    #include <conio.h>
    #include <time.h>
    #include <string>
    #include <windows.h>
    #include <vector>
    #include "class.h"
    using namespace std;
    
    void main(){
    	bool wahl_eingabe;
    	Tisch Spieltisch;
    	bjheader2();
    	//init_k_s();
    	while (Spieltisch.Spieler1.Guthaben>0){
    	int letzte_karte_sp1=0;
    	int letzte_karte_bk=0;
    	bjheader2();
    	Spieltisch.Bank.Handsumme=0;
    	Spieltisch.Spieler1.Handsumme=0;
    	Spieltisch.ers_misch();
    	Spieltisch.bieten();
    	Spieltisch.erster_zug();
    	bjheader2();
    	Spieltisch.ausg();
    	cout<<"Moechten Sie eine weitere Karte ziehen? Nein(0) Ja(1)"<<endl;
    	cin>>wahl_eingabe;
    	Spieltisch.wahl=wahl_eingabe;
    	Spieltisch.zug=2;
    	while(Spieltisch.wahl!=0){
    		Spieltisch.zug++;
    		Spieltisch.sp1_karte();
    		Spieltisch.Spieler1.Handsumme=Spieltisch.Spieler1.Handsumme + Spieltisch.Spieler1.Stapel[Spieltisch.Spieler1.Stapel.size() -1].Wert;
    		bjheader2();
    		Spieltisch.ausg_sp1(Spieltisch.zug);
    		cout<<"Moechten Sie eine weitere Karte ziehen? (Ja/Nein)"<<endl;
    		cin>>wahl_eingabe;
    		Spieltisch.wahl=wahl_eingabe;
    		}
    	Spieltisch.Bank.Handsumme=Spieltisch.Bank.Handsumme + Spieltisch.Bank.Stapel[1].Wert;
    	bjheader2();
    	Spieltisch.ausg_bk(Spieltisch.zug, Spieltisch.zug_bk);
    	cout<<"Die Bank ist nun an der Reihe!Bitte Warten!(wenn Bank Handsumme groesser als 16 ist Return druecken)"<<endl;
    	Sleep(2000);
    	Spieltisch.zug_bk=2;
    	while (Spieltisch.Bank.Handsumme<17){
    		Spieltisch.zug_bk++;
    		Spieltisch.bk_karte();
    		Spieltisch.Bank.Handsumme=Spieltisch.Bank.Handsumme + Spieltisch.Bank.Stapel[Spieltisch.Bank.Stapel.size() -1].Wert;
    		bjheader2();
    		Spieltisch.ausg_bk(Spieltisch.zug, Spieltisch.zug_bk);
    		Sleep(1500);
    	}
    	_getch();
    	if (Spieltisch.Spieler1.Guthaben==0){
    		cout<<"Sie sind Pleite. Kommen Sie wieder wenn Sie mehr Geld haben.";
    		break;
    	}
    	Spieltisch.loeschen();
    	bjheader2();
    	init_k();
    	}
    	_getch();
    }
    
    //class.h
    enum Symbole {Herz, Kreuz, Pik, Karo};
    enum BJ {Ja, Nein};
    char intToChar(int integer){return (char)integer+48;};
    struct K_Hilfe{
    	int Wert;
    	char Zeichen;
    	Symbole Symbol_h;
    };
    class Karten{
    public:
    	int Wert;
    	char Zeichen;
    	Symbole Symbol;
    	Karten();
    	Karten(int a, char b, Symbole c){
    		Wert = a;
    		Zeichen = b;
    		Symbol = c;
    	}
    };
    
    class Spieler{
    public:
    	string Name;
    	vector<Karten>Stapel;
    	int Guthaben,Handsumme; 
    	BJ BlackJack;
    	Spieler(){};
    };
    
    class Tisch{
    public:
    	vector<Karten>Kartenstapel;
    	Spieler Bank;
    	Spieler Spieler1;
    	bool wahl;
    	char vg, ausg_symbol; //vorzeitiger gewinn (BJ, überkauft,...)
    	int Gebot, zug, zug_bk; //zug = Anzahl der gezogenen Karten von Spieler1 (wichtig für Ausgabe)
    	//zug_bk = Anzahl der gezogenen Karten von Bank (wichtig für Ausgabe)
    	string spname;
    	Tisch(){
    		bjheader1();
    		Bank.Name="Bank";
    		cout<<endl<<"Bitte geben Sie ihren Namen ein: ";
    		cin>>spname;
    		Spieler1.Name=spname;
    		Spieler1.Guthaben=500;
    		Bank.Guthaben=500;
    		zug=2;
    		zug_bk=2;
    	}
    	//karten erstellen +  mischen
    	void ers_misch();
    	//bieten
    	void bieten();
    	//Spieler1 zieht eine Karte
    	void sp1_karte();
    	//Bank zieht eine Karte
    	void bk_karte();
    	//Bank zieht 2 Karten || Spieler1 zieht 2 Karten
    	void erster_zug();
    	//Bank 1 Karte ausgabe || Spieler1 2 Karten ausgabe
    	void ausg();
    	//2. Zug von Spieler1
    	void zweiter_zug_sp1();
    	//Ausgabe nur für Spieler1
    	void ausg_sp1(int l);
    	//Ausgabe für Spieler1 komplett und Bank
    	void ausg_bk (int m, int n);
    	//alle Karten löschen
    	void loeschen();
    };
    void Tisch::ausg_sp1(int l){
    	//Spieler1
    	cout<<Spieler1.Name<<":"<<endl;
    	cout<<endl;
    	cout<<endl<<"Handsumme:  "<<Spieler1.Handsumme<<endl<<endl;
    	for (int i=0; i<l; i++){
    		cout<<" ------     ";
    	}
    	cout<<endl;
    	for (int i=0; i<l; i++){
    		cout<<"| "<<Spieler1.Stapel[i].Zeichen<<"   "<<Spieler1.Stapel[i].Zeichen<<"|    ";
    	}
    	cout<<endl;
    	for (int i=0; i<l; i++){
    		cout<<"|      |    ";
    	}
    	cout<<endl;
    	for (int i=0; i<l; i++){
    		if(Spieler1.Stapel[i].Symbol==0){ausg_symbol=char(3);}
    		else if(Spieler1.Stapel[i].Symbol==1){ausg_symbol=char(5);}
    		else if(Spieler1.Stapel[i].Symbol==2){ausg_symbol=char(6);}
    		else if(Spieler1.Stapel[i].Symbol==3){ausg_symbol=char(4);}
    		cout<<"|   "<<ausg_symbol<<"  |    ";
    	}
    	cout<<endl;
    	for (int i=0; i<l; i++){
    		cout<<"|      |    ";
    	}
    	cout<<endl;
    	for (int i=0; i<l; i++){
    		cout<<"| "<<Spieler1.Stapel[i].Zeichen<<"   "<<Spieler1.Stapel[i].Zeichen<<"|    ";
    	}
    	cout<<endl;
    	for (int i=0; i<l; i++){
    		cout<<" ------     ";
    	}
    cout<<endl<<endl<<"°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°\n\n";
    	//Bank
    	cout<<"Bank:"<<endl;
    	cout<<endl;
    	cout<<endl<<"Handsumme:  "<<Bank.Handsumme<<endl<<endl;
    	for (int i=0; i<1; i++){
    		cout<<" ------      -------";
    	}
    	cout<<endl;
    	for (int i=0; i<1; i++){
    		cout<<"|"<<Bank.Stapel[i].Zeichen<<"    "<<Bank.Stapel[i].Zeichen<<"|    |*******|";
    	}
    	cout<<endl;
    	for (int i=0; i<1; i++){
    		cout<<"|      |    |** B **|";
    	}
    	cout<<endl;
    	for (int i=0; i<1; i++){
    		if(Bank.Stapel[i].Symbol==0){ausg_symbol=char(3);}
    		else if(Bank.Stapel[i].Symbol==1){ausg_symbol=char(5);}
    		else if(Bank.Stapel[i].Symbol==2){ausg_symbol=char(6);}
    		else if(Bank.Stapel[i].Symbol==3){ausg_symbol=char(4);}
    		cout<<"|   "<<ausg_symbol<<"  |    |*******|";
    	}
    	cout<<endl;
    	for (int i=0; i<1; i++){
    		cout<<"|      |    |** J **|";
    	}
    	cout<<endl;
    	for (int i=0; i<1; i++){
    		cout<<"|"<<Bank.Stapel[i].Zeichen<<"    "<<Bank.Stapel[i].Zeichen<<"|    |*******|";
    	}
    	cout<<endl;
    	for (int i=0; i<1; i++){
    		cout<<" ------      -------";
    	}
    	cout<<endl;
    }
    
    /*************************************************************************************************************
    *************************************************************************************************************/
    void Tisch::ausg_bk(int m, int n){
    	//Spieler1
    	cout<<Spieler1.Name<<":"<<endl;
    	cout<<endl;
    	cout<<endl<<"Handsumme:  "<<Spieler1.Handsumme<<endl<<endl;
    	for (int i=0; i<m; i++){
    		cout<<" ------     ";
    	}
    	cout<<endl;
    	for (int i=0; i<m; i++){
    		cout<<"| "<<Spieler1.Stapel[i].Zeichen<<"   "<<Spieler1.Stapel[i].Zeichen<<"|    ";
    	}
    	cout<<endl;
    	for (int i=0; i<m; i++){
    		cout<<"|      |    ";
    	}
    	cout<<endl;
    	for (int i=0; i<m; i++){
    		if(Spieler1.Stapel[i].Symbol==0){ausg_symbol=char(3);}
    		else if(Spieler1.Stapel[i].Symbol==1){ausg_symbol=char(5);}
    		else if(Spieler1.Stapel[i].Symbol==2){ausg_symbol=char(6);}
    		else if(Spieler1.Stapel[i].Symbol==3){ausg_symbol=char(4);}
    		cout<<"|   "<<ausg_symbol<<"  |    ";
    	}
    	cout<<endl;
    	for (int i=0; i<m; i++){
    		cout<<"|      |    ";
    	}
    	cout<<endl;
    	for (int i=0; i<m; i++){
    		cout<<"| "<<Spieler1.Stapel[i].Zeichen<<"   "<<Spieler1.Stapel[i].Zeichen<<"|    ";
    	}
    	cout<<endl;
    	for (int i=0; i<m; i++){
    		cout<<" ------     ";
    	}
    cout<<endl<<endl<<"°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°\n\n";
    	//Bank
    	cout<<"Bank:"<<endl;
    	cout<<endl;
    	cout<<endl<<"Handsumme:  "<<Bank.Handsumme<<endl<<endl;
    	for (int i=0; i<n; i++){
    		cout<<" ------     ";
    	}
    	cout<<endl;
    	for (int i=0; i<n; i++){
    		cout<<"|"<<Bank.Stapel[i].Zeichen<<"    "<<Bank.Stapel[i].Zeichen<<"|    ";
    	}
    	cout<<endl;
    	for (int i=0; i<n; i++){
    		cout<<"|      |    ";
    	}
    	cout<<endl;
    	for (int i=0; i<n; i++){
    		if(Bank.Stapel[i].Symbol==0){ausg_symbol=char(3);}
    		else if(Bank.Stapel[i].Symbol==1){ausg_symbol=char(5);}
    		else if(Bank.Stapel[i].Symbol==2){ausg_symbol=char(6);}
    		else if(Bank.Stapel[i].Symbol==3){ausg_symbol=char(4);}
    		cout<<"|   "<<ausg_symbol<<"  |    ";
    	}
    	cout<<endl;
    	for (int i=0; i<n; i++){
    		cout<<"|      |    ";
    	}
    	cout<<endl;
    	for (int i=0; i<n; i++){
    		cout<<"|"<<Bank.Stapel[i].Zeichen<<"    "<<Bank.Stapel[i].Zeichen<<"|    ";
    	}
    	cout<<endl;
    	for (int i=0; i<n; i++){
    		cout<<" ------     ";
    	}
    	cout<<endl;
    }
    
    void Tisch::loeschen(){
    	do{Bank.Stapel.pop_back();}while(Bank.Stapel.size()!=0);
    	do{Spieler1.Stapel.pop_back();}while(Spieler1.Stapel.size()!=0);
    	do{Kartenstapel.pop_back();}while(Kartenstapel.size()!=0);
    }
    

    In der ersten Runde läuft alles wunderbar.
    Und dann, in einer der folgenden Runden (wechselt immer oO) kommt die Meldung
    vector substitiute out of range. Beim Debuggen hab ich festgestellt, das der Fehler in der class.h in Zeile 197 kommt
    (cout<<"|"<<Bank.Stapel[i].Zeichen<<" "<<Bank.Stapel[i].Zeichen<<"| ";).

    Schonmal Danke und sagt bescheid wenn ich noch mehr vom Quellcode braucht.

    yedion

    Achja, ich benutze Visual Studio 2005 und habe Windows Vista, falls das noch wichtig ist



  • Leider kann man nicht sehen, wieviele Karten du in Bank.Stapel überhaupt hineingesteckt hast. Offensichtlich sind aber weniger drin als du glaubst.

    Drollig ist auch, dass du bei ausg_bk dem Tisch seine eigenen Member übergibst.
    Irgendwelche Funktionen ändern fröhlich die Member irgendwelcher Objekte, Kapselung ist nicht vorhanden.



  • Zusätzlich, solltest du dir merken, den Code auf wirklich Relevante Stellen zu kürzen, nämlich da wo du meinst der Fehler, Fehlverhalten findet statt.
    Weil ich lese mir den Code bestimmt nicht durch, und da bin ich nicht der einzige.



  • Das mit dem vielen Quelltext hat den Vorteil, das
    man schon mal einen groben Eindruck vom Programmstil
    bekommt. Man muss ja nicht jede Zeile lesen 😉
    Aber kann im Zweifel in anderen Zeilen nachsehen.

    Er hat ja geschrieben, das er den Fehler bei Zeile 197
    vermutet.

    Erzählt mir mal als C++ Nix-Ahnung:
    Sollte das, was bei ihm in class.h steht, nicht auf
    mehrere Dateien im Projekt verteilt werden?

    Und, wenn ich folgendes sehe:

    void Tisch::ausg_sp1(int l){
        //Spieler1
    

    muss ich automatisch an Redundanzen denken oder 😕

    Aber je nach dem für welche Schule, ist das eventuell gar nicht
    relevant.

    MfG f.-th.



  • f.-th. schrieb:

    Das mit dem vielen Quelltext hat den Vorteil, das man schon mal einen groben Eindruck vom Programmstil bekommt. Man muss ja nicht jede Zeile lesen 😉

    Zu lange Ausschnitte schrecken ab, und helfen auch nicht weiter (Wenn danach gefragt wird kann man es immer noch nachreichen).

    Davon abgesehen: Bitte lass das Forum deinen Text umbrechen, und mach dies nicht manuell.

    f.-th. schrieb:

    Erzählt mir mal als C++ Nix-Ahnung:
    Sollte das, was bei ihm in class.h steht, nicht auf mehrere Dateien im Projekt verteilt werden?

    Üblicherweise trennt man den Code in eine Header-/Sourcedatei pro Klasse. In manchen Fällen (bei recht kurzen Code, oder wenn Klassen direkt zusammen gehören [hier bietet sich dann aber eine innere Klasse an] trennt man häufig nicht).

    Yedion schrieb:

    ...

    1. Verwende für C oder C++ Code bitte statt den code-Tags die cpp-Tags (Wegen Syntaxhervorhebung).

    2. "void main" gibt und gab es auch noch nie in C++. "int main" ist Standardkonform [int main gibt explizit 0 zurück wenn kein anderer Returnwert angegeben wird].

    3. In C++ ist es üblich das man Variablen dann deklariert wenn man sie verwendet, und möglichst auch im gleichen Schritt initialisiert.

    4. Wenn du Hilfe erwartest solltes du Code so schreiben, das andere ihn lesen können.
    a) Man kann auch Code leserlich ausschreiben. Abkürzungen sind kontraproduktiv.
    b) Verwende einheitliche Einrückstile.
    c) Für Zeilen wie "do{Bank.Stapel.pop_back();}while(Bank.Stapel.size()!=0);" sollte man dir Notenabzug geben. Die Returntaste ist dazu da damit man sie auch einsetzt, zumal es sauber umgebrochen auch deutlich lesbarer wird.

    5. Ich bezweifel das der Code überhaupt laufen kann, es sei den du hast im Header auch includes.
    a) Tu dir selbst ein gefallen, und verwendet "using namespace" nicht in Headern.
    b) Man trennt Header/Source aus guten Grund in C++. Die Implementierung gehört daher in eine cpp.
    c) Zudem ist es üblich pro Klasse einen eigenen Header und eine eigene Sourcedatei zu schreiben.


Anmelden zum Antworten