Question

I'm trying to make a simple blackjack program. Sadly, I'm having problems right off the bat with generating a deck of cards.

#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;
}

I know my problem begins with me trying to assign the value '10' to a char. Obviously I couldn't get this to compile but I'm sure when I try to assign the card values to the vector deck I'll also get an error since I used variable type 'char'. Knowing what kind of variable type to use seems to be killing me. Also, would 'deck.push_back(card[j] suit[i]);' be the correct code to combine the card and suit, or do you have to put something between card[j] and suit[i]? I'd appreciate it if any of you could lead me in the right direction. Also as a little side note, this is part of a homework assignment so please don't just give me entire blocks of code. Thanks for your help.

Was it helpful?

Solution

Try to create class of Card with suit and card as a member and set it as a type of vector. Like

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;
}

also using enums instead of chars in suit and card would make it clearer.

OTHER TIPS

I think what you are looking to use is an enumeration. It will make your code clearer and resolve your problem.

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

The way you model it really depends on what you're trying to do.

Are you creating an actual game, and the data structures just need to support the gameplay?

If so, I'd create a card class, with an enum field for the suit and a numeric type (with values 1 - 13) for the face value.

On the other hand, if you're building an analysis application or an AI player, then the model might be a little bit different.

A few years ago, I wrote a simulator to calculate probabilities in various Texas Holdem scenarios, and I wanted it to crunch numbers REALLY quickly. I started out with a very straightforward model (card class, suit enum, etc) but after a lot of profiling and optimization, I ended up with a bitwise representation.

Each card was a sixteen-bit value, with the thirteen high-order bits representing the face value, the two low order bits representing the suit, and with bit[2] as a special flag indicating an ace (used only in cases where the ace might appear in an A2345 straight).

Here are a few examples:

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

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

You can imagine how, with a design like this, it's lighting fast to look for pairs, threes-of-a-kind, and straights (flushes are slightly more tricky).

I won't go into all the particular operations, but suffice it to say that this kind of model supports millions of operations per second...

Of course, keep in mind, I'm not actually advocating that you use a design like this in a straightforward game implementation. The only reason I ended up with this design is because I needed to conduct massive statistical simulations.

So think carefully about how you want to model:

  • Each card
  • A player's hand
  • The entire deck
  • The state of the table... including all player hands (including players who have split their initial hand), maybe a six-deck shoe, the discard pile, etc

The overall application model, and the goals of the application in general, will determine to a large extent the types of data structures that'll be most appropriate.

Have fun!!!

Use 'T' instead of 10.

Have you tried replacing J with 11, Q with 12 and K with 13? Then you could use integers rather than characters. Replace 11-13 with the appropriate letter later on.

Well, first of all, deck[0] is one char, yet you are trying, to stuff "2h" into it. (for the moment, we'll ignore that how you are doing that is wrong.)

Basically, you'll need to make deck a vector<std::string>. Make card an array of const char*s, and convert the elements to string.

then use:

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

As mentioned by others, you can use 'T' for ten, J, Q, and K for the figures. As far as push_back.. since deck is a vector of chars, you can pass only one char to push_back as argument. Passing both the card value (1...9, T, J, Q, K) and its suite doesn't work.

I personally would create a little struct, to represent a Card, with a Value and a Suite property. Then, you can make your deck a vector of Cards .

Edited: fixing last word since vector (less-than) Card (greater-than) was rendered as vector (nothing).

This might not compile, but here is the approach I would (and have used). You're going to want to use ints to represent your cards, but you can easily abstract this in a class. Which I'll write for you.

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;
}

Now its very simple to add to this class to get everything you want out of it. To generate the list its as simple as below.

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

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

Do you need to shuffle?

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

How about see what the value of the first card is?

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

I didn't compile any of this, but it should be close.

Since this is a blackjack program, you will be adding and comparing the value of the cards.

That being the case, you can save yourself some additional programming and pain by giving the cards int values (1-13) instead of char values.

When I created my C++ Deck of cards class, I ran into a few problems of my own. First off I was trying to convert my PHP deck of cards class to C++, with minimal luck. I decided to sit down and just put it on paper. I decided to go with an Object Oriented setup, mostly because I feel it's the easiest to use for expansion. I use the objects Card and Deck, so, for instance, if you want to put 10 decks into the Shoe of your blackjack game, you could create 10 decks, which would be simple enough, because I decided to make everything self contained. In fact, it's so self contained, to create your shoe the code would be:

#include "AnubisCards.cpp"

int main() {

    Deck *shoe = new Deck(10);

}

But, that was for simplicity, not exactly necessary in smaller games where you only need a single deck.

ANYWAY, How I generated the deck was by creating an array of 52 Card objects. Decks are easy enough, because you know that you have 4 Suits and 13 Cards in each suit, you also know that you have 2,3,4,5,6,7,8,9,10,Jack,Queen,King,Ace in every single suit. Those will never change. So I used two loops, one for the Suit and the other for the Value.

It was something like this:

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

Now, you'll notice in every single one of those loops, I use an integer value. The reason is simple, cards are numbers. 4 suits. 13 values. Even the numerical value in the game of Blackjack. Face value, until you hit Face cards, which are numerical value 10 until you hit Ace which is numerical value 1 or 11. Everything is numbers. So you can use those numbers to not only assign the value of the card, but the suit of the card, and the number in the numerical sequence.

One idea would be to store a map in the Card class, with the char or String names of the cards, with 1,2,3... being the indexes for each.

I would go with Ross's suggestion to use integers. Most card games will involve some bits of math so that's a better representation.

Convert to 'A' or 'ACE' etc. on output.

Since this is homework for C++ I am going to guess you are expected to use classes. Otherwise use the enums, and if this were C use a struct or something.

And for some games, apart from points value, you'd want to store some kind of rank for the card, which would depend on the current mode of play.

I haven't done plain C in forever, but I mean something like this:

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;
}

Output looks like:

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 is boring. This code does compile.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top