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
#inc
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).
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.
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.
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.
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};
Use 'T' instead of 10.