Frage

Ich versuche, ein einfaches Blackjack-Programm zu machen. Leider bin ich mit der Erzeugung ein Karten Probleme auf Anhieb mit.

#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<char> deck;
    char suit[] = {'h','d','c','s'};
    char card[] = {'2','3','4','5','6','7','8','9','10','J','Q','K','A'};
    for (int j=0; j<13; j++) {
        for (int i=0; i<4; i++) {
            deck.push_back(card[j] suit[i]);
        }       
    }

    return 0;
}

Ich weiß, dass mein Problem beginnt mit mir versuchen, den Wert ‚10‘ zu einem Zeichen zuzuordnen. Offensichtlich konnte ich nicht bekommen, dies zu kompilieren, aber ich bin sicher, wenn ich versuche, die Kartenwert auf das Vektor Deck zuweisen werde ich auch einen Fehler, da ich Variablentyp ‚char‘ verwendet. Zu wissen, welche Art von Variablentyp scheint zu verwenden, mich zu töten werden. Auch würde 'deck.push_back (Karte [j] Anzug [i]);' sein der richtige Code die Karte und Anzug zu kombinieren, oder müssen Sie etwas zwischen Karte [j] gesetzt und Anzug [i]? Ich würde es begrüßen, wenn jemand von euch mich in der richtigen Richtung führen könnte. Auch als kleine Randnotiz, ist dies Teil einer Hausaufgabe also bitte nicht nur mir gesamte Code-Blöcke geben. Vielen Dank für Ihre Hilfe.

War es hilfreich?

Lösung

Versuchen Sie, mit Anzug und Karte als Mitglied der Klasse von Karte zu erstellen und sie als eine Art von Vektor-Set. Wie

public class Card {
 public:
  Card(char suit, char card);
  char suit, card;
};

int main() {
    vector<Card> deck;
    char suit[] = {'h','d','c','s'};
    char card[] = {'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
    for (int j=0; j<13; j++) {
        for (int i=0; i<4; i++) {
                deck.push_back(new Card(card[j],suit[i]));
        }               
    }
    return 0;
}

auch Aufzählungen anstelle von Zeichen in Anzug und Karte wäre es klarer machen.

Andere Tipps

Ich denke, was Sie suchen, ist eine Aufzählung zu verwenden. Es wird Ihren Code klarer und lösen Ihr Problem machen.

enum SUIT { HEART, CLUB, DIAMOND, SPADE }; 
enum VALUE { ONE, TWO, THREE, ..., TEN, JACK, QUEEN, KING};

So wie du es wirklich modellieren hängt davon ab, was Sie zu tun versuchen.

Sind Sie ein aktuelles Spiel zu schaffen, und die Datenstrukturen müssen nur das Gameplay unterstützen?

Wenn ja, würde ich eine Karte Klasse erstellen, mit einem Enum Feld für den Anzug und einen numerischen Typen (mit Werten von 1 bis 13). Für den Nennwert

Auf der anderen Seite, wenn Sie eine Analyse-Anwendung oder einen KI-Spieler Gebäude sind, dann könnte das Modell ein wenig anders sein.

Vor einigen Jahren schrieb ich ein Simulator Wahrscheinlichkeiten in verschiedenen Texas Holdem Szenarien zu berechnen, und ich wollte es Zahlen wirklich schnell knirschen. Ich begann mit einem sehr einfachen Modell (Karte Klasse, Anzug ENUM, etc), aber nach vieler Profilierung und Optimierung, ich endete mit einer bitweise Darstellung auf.

Jede Karte war ein Sechzehn-Bit-Wert, mit den dreizehn Bits hoher Ordnung den Nominalwert darstellt, wobei die beiden niederwertigen Bits der Anzug darstellt, und mit dem Bit [2] als ein spezielles Flag ein As angibt (wird nur in Fälle, in denen das Ass in einem A2345 gerade erscheinen könnte).

Hier sind einige Beispiele:

0000000000001001  <----  Two of hearts
0100000000000011  <----  King of spades
1000000000000110  <----  Ace of diamonds

^^^^^^^^^^^^^            ("face-value" bits)
             ^           ("low-ace" flag)
              ^^         ("suit" bits)

Sie können sich vorstellen, wie, mit einem Design, wie diese, es schnell ist die Beleuchtung für Paare zu suchen, zu dritt-of-a-kind und Straights (Wallungen sind etwas komplizierter).

Ich werde nicht gehen in alle bestimmte Operationen, aber es genügt zu sagen, dass diese Art von Modell Millionen Operationen pro Sekunde unterstützt ...

Natürlich, denken Sie daran, ich bin nicht dafür eigentlich, dass Sie ein Design wie dies in einer einfachen Spiel-Implementierung verwenden. Der einzige Grund, warum ich mit diesem Entwurf gelandet ist, weil ich massive statistische Simulationen durchzuführen, benötigt werden.

So sorgfältig darüber nachdenken, wie Sie modellieren mögen:

  • Jede Karte
  • der Hand eines Spielers
  • Das gesamte Deck
  • Der Zustand des Tisches ... einschließlich aller Spieler Hände (einschließlich Spieler, die ihre ursprüngliche Hand geteilt haben), vielleicht ein Sechs-Deck Schuh, der Ablagestapel, usw.

Das allgemeine Anwendungsmodell und die Ziele der Anwendung in der Regel werden die Arten von Datenstrukturen in hohem Maß bestimmen, die am besten geeignet sein werden.

Haben Sie Spaß !!!

Mit 'T' statt 10.

Haben Sie mit 11 ersetzen J versucht, Q mit 12 und K mit 13? Dann könnten Sie integers anstatt characters verwenden. Ersetzen 11-13 mit dem entsprechenden Buchstaben später.

Nun, zunächst einmal, Deck [0] ist ein Zeichen, aber Sie versuchen, „2h“ hinein zu stopfen. (Für den Moment, wir ignorieren, dass, wie Sie tun, dass falsch ist.)

Im Grunde müssen Sie Deck einen vector<std::string> machen. Make-Karte ein Array von const char * s, und wandeln die Elemente zu bespannen.

dann verwenden:

deck.push_back(std::string(card[j]) + suit[i]);

Wie bereits von anderen erwähnt, können Sie ‚T‘ für zehn, J, Q und K für die Figuren verwenden. Soweit push_back .. da Deck ein Vektor von Zeichen ist, können Sie nur ein Zeichen push_back als Argument übergeben. Passing sowohl den Kartenwert (1 ... 9, T, J, Q, K) und seine Suite funktioniert nicht.

Ich persönlich würde eine wenig Struktur erstellen, um eine Karte zu repräsentieren, mit einem Wert und einer Suite Eigenschaft. Dann können Sie Ihr Deck ein Vektor-Karten machen.

Editiert: Fixierung letztes Wortes seit Vektor (weniger als) Karte (Größer als) als Vektor (nichts) gemacht

.

Das kann nicht kompiliert werden, aber hier ist der Ansatz, den ich würde (und haben) verwendet. Sie gehen zu wollen Ints benutzen, um Ihre Karten zu vertreten, aber man kann dies in einer Klasse leicht abstrakt. Welche werde ich für Sie schreiben.

class Card
{
public:
    enum ESuit
    {
        kSuit_Heart,
        kSuit_Club,
        kSuit_Diamond,
        kSuit_Spade,
        kSuit_Count
    };

    enum ERank
    {
        kRank_Ace,
        kRank_Two,
        kRank_Three,
        kRank_Four,
        kRank_Five,
        kRank_Six,
        kRank_Seven,
        kRank_Eight,
        kRank_Nine,
        kRank_Ten,
        kRank_Jack,
        kRank_Queen,
        kRank_King,
        kRank_Count
    };

    static int const skNumCards = kSuit_Count * kRank_Count;

    Card( int cardIndex )
    : mSuit( static_cast<ESuit>( cardIndex / kRank_Count ) )
    , mRank( static_cast<ERank>( cardIndex % kRank_Count ) )
    {}

    ESuit GetSuit() const { return mSuit );
    ERank GetRank() const { return mRank );

private:
    ESuit mSuit;
    ERank mRank;
}

Nun ist es sehr einfach zu dieser Klasse hinzuzufügen, alles, was man aus ihm heraus erhalten möchten. Zur Erzeugung der Liste seines so einfach wie unten.

rstl::vector<Card> mCards;
mCards.reserve( Card::skNumCards );

for ( int cardValue = 0; cardValue < Card::skNumCards; ++cardValue )
{
    mCards.push_back( Card( cardValue ) );
}

Müssen Sie mischen?

#include <algorithm>
std::random_shuffle( mCards.begin(), mCards.end() );

Wie sei es zu sehen, was der Wert der ersten Karte ist?

if ( mCards[0].GetSuit() == Card::kRank_Club && mCards[0].GetRank() == Card::kRank_Ace )
{
    std::cout << "ACE OF CLUBS!" << std::endl;
}

Ich habe nichts davon kompilieren, aber es sollte in der Nähe sein.

Da dies ein Blackjack-Programm ist, werden Sie das Hinzufügen und den Wert der Karten zu vergleichen.

Wenn das der Fall, können Sie sparen Sie sich einige zusätzliche Programmierung und Schmerz, indem sie die Karten int Werte (1-13) anstelle von char Werte.

Wenn ich erstellt meine C ++ Deck von Karten Klasse , ich lief in ein paar Probleme meiner eigenen. Zunächst einmal habe ich versucht rel="nofollow"> zu C ++, mit minimalem Glück. Ich beschloss, sich hinsetzen und es nur auf Papier. Ich beschloss, mit einer objektorientierten Einrichtung zu gehen, vor allem, weil ich glaube, es ist die einfachste für die Expansion zu verwenden. Ich verwende die Objekte Karte und Deck , so zum Beispiel, wenn Sie 10 Decks in die Schuh setzen wollen Ihres Blackjack-Spiel, Sie schaffen könnten 10 Decks, die einfach genug sein würde, weil ich alles selbst enthalten sind, machen entschieden. In der Tat ist es so enthalten selbst, erstellen Sie Ihren Schuh würde der Code:

#include "AnubisCards.cpp"

int main() {

    Deck *shoe = new Deck(10);

}

Aber, das war die Einfachheit halber nicht genau notwendig in kleineren Spielen, in denen Sie nur ein einziges Deck benötigen.

Wie auch immer, wie I erzeugen das Deck war durch eine Reihe von 52-Karte Objekten zu schaffen. Decks sind einfach genug, weil Sie wissen, dass Sie 4 Suits und 13 Karten in jeder Farbe , wissen Sie auch, dass Sie 2,3,4,5 , 6,7,8,9,10, Bube, Dame, König, Ass in jedem Anzug . Die werden sich nie ändern. So habe ich zwei Schleifen, eine für den Anzug und die andere für das Wert .

Es war so etwas wie folgt aus:

for(int suit = 1; suit <= 4; suit++){
    for(int card = 1; card <= 13; card++){
        // Add card to array
    }
}

Nun, werden Sie in jedem einzelnen dieser Schleifen bemerken, verwende ich einen ganzzahligen Wert. Der Grund ist einfach, Karten sind Zahlen. 4 Anzüge. 13 Werte. Auch der Zahlenwert im Spiel von Blackjack. Nominale, bis Sie Bildkarten getroffen, die 10 Zahlenwert ist, bis Sie Ace getroffen, die 1 Zahlenwert ist oder 11. Alles ist Zahlen. So können Sie diese Zahlen verwenden, um nicht nur den Wert der Karte zuweisen, aber die Farbe der Karte, und die Zahl in der numerischen Folge.

Eine Idee wäre, eine Karte in der Klasse Karte zu speichern, mit den Zeichen oder String Namen der Karten, mit 1,2,3 ... für jeden den Indizes zu sein.

Ich würde mit Ross Vorschlag geht ganze Zahlen zu verwenden. Die meisten Kartenspiele werden einige Bits der Mathematik beteiligt, so dass eine bessere Darstellung.

Konvertieren in 'A' oder 'ACE' usw. auf der Produktion.

Da diese Hausaufgaben für C ++ Ich werde Sie erraten, wird erwartet, dass Klassen verwenden. Ansonsten die Aufzählungen verwenden, und wenn diese C eine Struktur oder etwas verwenden waren.

Und für einige Spiele, abgesehen von den Punkten Wert, würden Sie eine Art von Rang für die Karte gespeichert werden sollen, die auf dem aktuellen Modus des Spiels abhängen würden.

Ich habe nicht einfach in C in immer getan, aber ich meine, so etwas wie folgt aus:

typedef struct struct_card {
  unsigned short int suit:2;
  unsigned short int card:4;
//  unsigned short int valu:4;
} card;

int main() {
  card a_card;
  card std_deck[52];
  const unsigned short int rummy_value[13] = {1,2,3,4,5,6,7,8,9,10,10,10,10};
  const char *std_card_name[13] = {"Ace","Two","Three","Four","Five","Six",
    "Seven","Eight","Nine","Ten","Jack","Queen","King"};
  const char *std_suit_name[4] = {"Spades","Clubs","Hearts","Diamonds"};

  int j, k, i=0;
  for(j=0; j<4; j++){
    for(k=0; k<13; k++){
      a_card.suit=j; a_card.card=k;
      std_deck[i++] = a_card;
    }
  }

  //check our work
  printf("In a game of rummy:\n");
  for(i=0;i<52;i++){
    printf("  %-5s of %-8s is worth %2d points.\n",
        std_card_name[std_deck[i].card],
        std_suit_name[std_deck[i].suit],
        rummy_value[std_deck[i].card]);
  }

  //a different kind of game.
  enum round_mode {SHEILD_TRUMP, FLOWER_TRUMP, BELL_TRUMP, ACORN_TRUMP, BOCK, GEISS} mode;
  const card jass_deck[36]={
    {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},
    {1,1},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},
    {2,2},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},
    {3,3},{3,1},{3,2},{3,3},{3,4},{3,5},{3,6},{3,7},{3,8},
  };
#define JASS_V {11,0,0,0,0,10,2,3,4}
  const unsigned short int jass_value[9] = JASS_V;
#define JASS_TRUMP_V {11,0,0,0,14,10,20,3,4}
  const unsigned short int jass_trump_value[9] = JASS_TRUMP_V;
#define JASS_BOCK_V {11,0,0,8,0,10,2,3,4}
  const unsigned short int jass_bock_value[9] = JASS_BOCK_V;
#define JASS_GEISS_V {0,11,0,8,0,10,2,3,4}
  const unsigned short int jass_geiss_value[9] = JASS_GEISS_V;
  const char *jass_card_name[9] = {"Ace","Six","Seven","Eight","Nine","Banner",
    "Under","Ober","King"};
  const char *jass_suit_name[4] = {"Sheilds","Flowers","Bells","Acorns"};
  const unsigned short int jass_all_value[6][4][9] = {
    { JASS_TRUMP_V, JASS_V, JASS_V, JASS_V },
    { JASS_V, JASS_TRUMP_V, JASS_V, JASS_V },
    { JASS_V, JASS_V, JASS_TRUMP_V, JASS_V },
    { JASS_V, JASS_V, JASS_V, JASS_TRUMP_V },
    { JASS_BOCK_V, JASS_BOCK_V, JASS_BOCK_V, JASS_BOCK_V },
    { JASS_GEISS_V, JASS_GEISS_V, JASS_GEISS_V, JASS_GEISS_V }
  };

  //check our work 2: work goes on summer vacation
  printf("In a game of jass with trump (Sheilds | Flowers | Bells | Acorns) | Bock | Geiss\n");
  for(i=0;i<36;i++){
    printf("  %-6s of %-7s is worth %8d%10d%8d%9d%8d%8d\n",
        jass_card_name[jass_deck[i].card],
        jass_suit_name[jass_deck[i].suit],
        jass_all_value[SHEILD_TRUMP][jass_deck[i].suit][jass_deck[i].card],
        jass_all_value[FLOWER_TRUMP][jass_deck[i].suit][jass_deck[i].card],
        jass_all_value[BELL_TRUMP][jass_deck[i].suit][jass_deck[i].card],
        jass_all_value[ACORN_TRUMP][jass_deck[i].suit][jass_deck[i].card],
        jass_all_value[BOCK][jass_deck[i].suit][jass_deck[i].card],
        jass_all_value[GEISS][jass_deck[i].suit][jass_deck[i].card]);
  }
  return 0;
}

Ausgabe wie folgt aussieht:

In a game of rummy:
  Ace   of Spades   is worth  1 points.
  Two   of Spades   is worth  2 points.
  Three of Spades   is worth  3 points.
  Four  of Spades   is worth  4 points.
  Five  of Spades   is worth  5 points.
...
  Nine  of Diamonds is worth  9 points.
  Ten   of Diamonds is worth 10 points.
  Jack  of Diamonds is worth 10 points.
  Queen of Diamonds is worth 10 points.
  King  of Diamonds is worth 10 points.
In a game of jass with trump (Sheilds | Flowers | Bells | Acorns) | Bock | Geiss
  Ace    of Sheilds is worth       11        11      11       11      11       0
  Six    of Sheilds is worth        0         0       0        0       0      11
  Seven  of Sheilds is worth        0         0       0        0       0       0
  Eight  of Sheilds is worth        0         0       0        0       8       8
  Nine   of Sheilds is worth       14         0       0        0       0       0
  Banner of Sheilds is worth       10        10      10       10      10      10
...
  Under  of Acorns  is worth        2         2       2       20       2       2
  Ober   of Acorns  is worth        3         3       3        3       3       3
  King   of Acorns  is worth        4         4       4        4       4       4

Blackjack ist langweilig. Dieser Code nicht kompiliert.

scroll top