Stack bei Blackjack-Spiel
-
Hallo, ich möchte ein Blackjack-Spiel schreiben. Hierzu habe ich mir eine Template-Klasse Stack geschrieben, welche die Kartenstapel auf nimmt. Da ich noch kleinere Veränderungen beim Stack vornehmen werde, habe ich nicht auf die STL zurückgegriffen.
Hier zunächst meine Header für den Stack:#ifndef _Stack_h #define _Stack_h template <class T, int x> class Stack { private: T Karte[x]; int anzahl; public: Stack(void); void push (T); T pop (void); }; template<class T, int x> Stack<T,x>::Stack(void) { anzahl = 0; for(int i = 0;i<x;i++) { Karte[i]=0; } } template <class T, int x> void Stack<T,x>::push (T value) { T zwsp; if(anzahl == 1) Karte[1]=Karte[0]; else if(anzahl>=2&&anzahl<=x) { for(int i = anzahl-2;i>=0;i--) { zwsp = Karte[i]; Karte[i+1] = zwsp; } } Karte[0] = value; anzahl++; } template <class T, int x> T Stack<T,x>::pop(void) { T value = Karte[0]; T zwerg; for(int i = 0;i<anzahl;i++) { zwerg = Karte[i+1]; Karte[i]=zwerg; } Karte[anzahl-1] = 0; anzahl--; return value; } #endif
Ich werde im Nachhinein noch kurze Implementierungen vornehmen, wenn der Stack voll ist, etc. Die Klasse steht nur testweise eigentlich.
Jetzt habe ich in meiner File BlackJack.cpp die Klasse BlackJack erstellt, welche 4 Kartenstapel (für die einzelnen Farben) enthält, einen Spielerkartenstapel, einen PC-Kartenstapel (welche beim Ziehen der Karten gefüllt werden sollen) und einen Kartenstapel, welcher den Anfangsstapel darstellt, auf dem die Karten gemischt werden und hinaufgelegt werden.
Beim push und pop der einzelnen Kartenstapel für die Farben funktioniert das einwandfrei, jedoch,wenn ich die Kartenstapel auf den Anfangsstapel mische, und anschließend testweise das Ergebnis des Vorgangs mittels pop vom Kartenstapel hole, gibt dieser mir immer den gleichen Wert aus, jetzt weiß ich derzeit nicht mehr weiter, vllt sieht irgendwer Fehler (außer der Überprüfungen auf Kapazität im Stack), die mich in diese Bredouille gebracht haben. Ich weiß jedenfalls nicht mehr weiter. Hier noch die Klasse BlackJack(die ebenfalls noch nicht fertiggestellt ist, da es beim Mischen schon Probleme gibt), inklusive main (die noch nicht wirklich viel macht):
#include <iostream> #include <conio.h> #include <iomanip> #include <time.h> #include "Stack.h" using namespace std; class BlackJack { private: Stack<int,21> Karten[4]; Stack<int,84> Stapel; Stack<int,84> Spieler; Stack<int,84> PC; public: void mischen (void); void ziehen (void); void KI (void); void ausgabe (void); BlackJack(void); }; BlackJack::BlackJack(void) { for(int i = 0;i<21;i++) { Stapel.push(0); Spieler.push(0); PC.push(0); } } void BlackJack::mischen (void) { int size = 21; int feld[size]; bool x[size]; int l = 0; for(int i = 0;i<21;i++) feld[i]=i+1; for(int i = 0;i<4;i++) { for(int p = 0;p<21;p++) x[p] = false; for(int k = 0;k<21;k++) { do { l = rand()%21; }while(x[l] == true); Karten[i].push(feld[l]); x[l]=true; } } for(int i = 0;i<21;i++) { Stapel.push(Karten[0].pop()); Stapel.push(Karten[1].pop()); Stapel.push(Karten[2].pop()); Stapel.push(Karten[3].pop()); } for(int i = 0;i<84;i++) { cout<<Stapel.pop()<<endl; } } int main () { system("color f0"); BlackJack Spiel; Spiel.mischen(); getch(); return 0; }
Thx so far
-
Deine Frage war ja sehr versteckt..
Ich habe gleich eine Gegenfrage für dich:
Wenn du am Stack eh nur "kleine" Änderungen machen möchtest, warum nutzt du dann nicht *doch* die Funktionalität des std::stacks und leitest deine Klasse davon ab?Dann müsstest du dir um solche Dinge wie "Stapel" zusammenlegen keine Sorgen mehr machen.
-
Des stimmt, eigentlich keine schlechte Idee, dann werd ich mal zusehen, dass ich des vernünftig hin bringe, warum bin ich net gleich auf Vererbung gekommen, ich werde es mal mit der Implementierung mittels des Stacks probieren, könnte man ja echt ableiten, und wenns Fehler gibt, bin ich net schuld
Ich werds erstmal so versuche, wenn ichs net schaffe, oder ihr Fehler entdeckt, könntet ihr des ja hier posten
-
Dann bin ich ja froh dich auf den rechten Weg der Tugend gebracht zu haben.
-
hehejo schrieb:
Wenn du am Stack eh nur "kleine" Änderungen machen möchtest, warum nutzt du dann nicht *doch* die Funktionalität des std::stacks und leitest deine Klasse davon ab?
a) weil ich meyers gelesen hab und weiß, daß ich hier nicht erben soll und darf, sondern layering das angesagte mittel wäre.
b) weil ich noch viel üben muß und der stack mir jetzt genau gelegen kommt, ich bin motiviert und die schwirigkeit ist gerade so, daß ich es schaffen werde, auch wenn es anstrengend ist.
c) weil ich mal ein supi programmierer werden will, und onkel volkard hat gesagt, daß man dazu die grundlagen gründlich lernen muß.
d) weil ich masochist bin.
e) weil der stl-stack eigentlich nur eine datanstruktur namens keller ist, die push und pop halt hat, während ein kartenstapel einfach was ganz anderes ist, größenbeschränlt, mit mischen und zusammenführen und so. die heißen auf englisch nur zufällig beide stack.
f) weil der eigene stack hier furchbar viel schneller ist.
g) weil es mich so mit stolz erfüllt, wenn ich was schwieriges hinkriege.
h) weil ich im gefühl habe, daß mein stack fürchterlich stinkt, und den gestank nur loswerde, wenn ich noch ein paarmal reimplemetiere. das schneide ich mir mit srl-verwendung ab.
i) weil der nachher entstehende saubere stack nullinger mehr vom stl-stack profitieren würde.
j) weil ich mir noch nicht sicher bin, ob ich ne klasse fpr die spielkarten brauche und mic das auch alle verwirrt.
k) weil ich mir doch sicher bin, daß ich ne klasse fpr die spielkarten brauche und mic das auch alle verwirrt.
l) weil ich unbedingt in pop ne schleife haben wollte (warum eigentlich?)Dann müsstest du dir um solche Dinge wie "Stapel" zusammenlegen keine Sorgen mehr machen.
ich denke, die sorgen würden durchaus die gleichen sein, wenn die gemeinsamen sorgen davor weg wären.
-
hehejo schrieb:
Dann bin ich ja froh dich auf den rechten Weg der Tugend gebracht zu haben.
ich nicht. stl-stack wäre hier falsch. also speicherfressend, unsinnig, deplaziert, schlecht wartbar, falsch vererbt und lahm. aber jeder muß seine erfahrungen selber machen.
-
Entweder das war ironisch gemeint, oder ich soll dich ernst nehmen, das weiß ich derzeit nicht so ganz einzuschätzen. Das mit der Schleife in meinem Stack ist wohl ein berechtigter Einwand, weil ich auch eigentlich den Index, bei dem auf den Stack mit pop zugegriffen wird, verschieben kann, wenn ich das dann will. Außerdem ist es doch prinzipiell egal, ob ich Sachen, wie einen Stack selbst implementieren will, oder den aus der STL hole, da es ja eigentlich wurscht sein kann, was ich will, wollte ja bloß mal anfragen, ob einer von euch evtl. einen Ansatzpunkt sieht, warum der Stack hier bei der pop-Methode nen Fehler baut, ich wollte hier lediglich eine Frage stellen und diese vernünftig beantwortet kriegen...
Naja egal, dann bastel ich halt weiter, auch wenn ich hier scheinbar nicht so viel Zuspruch erhalte, wie erhofft...
Und abgesehen davon halte ich einen Stack als Implementierung für einen Kartenstapel ja schon für sinnvoll, da man ja beim Blackjack, oder überhaupt bei Kartenspielen die Karten (meistens) von oben ab hebt und gibt etc. von daher ist ja wohl ein Stack, der mittels pop die Karten von oben ab hebt, schon sinnvoll...
Egal ^^
-
war nicht ironisch gemeint, vorallem ist punkt a der wichtigste
-
kk dann danke
-
Vorden schrieb:
Entweder das war ironisch gemeint, oder ich soll dich ernst nehmen, das weiß ich derzeit nicht so ganz einzuschätzen.
es ist auch nicht meine absicht, daß man das genau einschätzen kann.
naja, wenn du magst, schreibe ich mal, was mir so dringend aufföllt.
aber alles ungetestet, der code hat keinen compiler gesehen.
und ist nur mal ein kleiner ansatz. na, eigentlich genau, was du auch gemacht hast, nur mit
weniger if und for. und ich gehe davon aus, daß nach dem erste mal, daß das spiel geht,
du eh so viele neue ideen hast, daß du es nochmal neu machst und dann doppelt so gut.typedef int Karte; template<class T,int size> class Array{ T data[size]; public: T& operator[](int index){ assert(indexIstGültig); return data[index]; } }; template <class T, int size> class Stack { private: Array<T,size> data; int anzahl; public: Stack(){ anzahl=0; } void push (T const& t){ data[anzahl++]=t; } void pop (){ --anzahl; } T& peek(){ return data[anzahl-1]; } }; class Kartenstapel:public Stack<Karte,84>{ public: void mischen(){ for(int i=0;i<anzahl;++i) swap(data[i],data[rand()%anzahl]); } }; KartenStapel neuerStapel(){ KartenStapel result; for(int i=0;i<4;++i) for(int j=0;j<21;++j) result.push(j); result.mischen(); return result; }; class BlackJack { private: Stack<Karte,84> Stapel; Stack<karte,84> Spieler; Stack<karte,84> PC; public: }; BlackJack::BlackJack(void) :Stapel(neuerStapel()) { } void BlackJack::mischen (void) { Stapel.mischen(); }
-
Hmm, k, wär ok, ich hatte auch schon nen Ansatz mit ner Array-Klasse, aber ich dachte, ich hätte es leichter gelöst... Naja, ich hab halt immer die Indizes verschoben, dass es erste ganz vorne stand und net die Zahl im nachfolgenden Arrayelement ausgegeben wurde, deswegen diese for-Schleifen Konstruktionen zum rumkopieren. Ansonsten is es jetz ähnlich dem, was ich mir inzwischen zusammengebastelt habe, jedoch, warum du nen typedef machst, is mir net ganz schlüssig, ich hätte einfach int stehen lassen, weil ich muss net unbedingt anzeigen, dass ich eigentlich Karten spiele und net int
aber danke soweit
-
Vorden schrieb:
jedoch, warum du nen typedef machst, is mir net ganz schlüssig, ich hätte einfach int stehen lassen, weil ich muss net unbedingt anzeigen, dass ich eigentlich Karten spiele und net int
aber danke soweitgrundregel: ein begriff in der außenwelt kriegt auch nen typen in der simulation.
hätten das mal alle nasen mit der postleitzahl gemacht, wäre die umstellung auf 5-stellige postleitzahlen billig gewesen. und ähnlich mit dem y2k-problem.a) ups, ein char reicht ja. typedef char Karte;
b) ups, ein enum ist noch schöner. enum...
c) nee, char oder int sind doch besser.
d) ich mach ne class draus und überlade den op<<, damit er klartext anzeigt
e) ich überlade den op==, damit er nur nach wert vergleicht und nicht nach farbe und speicher die farben als die letzten 3 bits und den wert als die ersten 5 oder so.
f) ich englischifiziere den code (warum eigentlich?) und nenne die Karte Card und den KartenStack endlich Deck.
g) wenn sich was wichtiges an der Card ändert, nenne ich sie einfach CardNew und compilier nochmal und schau bei allen verwendungen (jetzt compilerfehler, lpckenlos entdeckt), ob die wichtige änderung kompatibel mit dem code ist.
h) ich kann am typen der funktionen sehen, was lost ist!!! also int ki()?? oder Karte ki()!
-
volkard schrieb:
hätten das mal alle nasen mit der postleitzahl gemacht, wäre die umstellung auf 5-stellige postleitzahlen billig gewesen. und ähnlich mit dem y2k-problem.
wenn du es schaffst, einen c++-compiler auf einer PDP-11 zu implementieren, dann bekommst du den nobelpreis im maschinencoden