//----------------- CARDDECK.CPP ----------------- // This file contains the definitions for the // classes Card and Deck. #include // for cout #include // for rand(), srand() #include // for clock() #include "carddeck.h" using namespace std; // card class member functions ostream& operator<< (ostream& os, const Card& c) { c.Display(os); // call display to help return os; // return the stream for cascading } void Card::Display(ostream& os) const // display the suit and value of an individual card { if ((2 <= val) && (val <= 10)) // for number cards, show value os << val; else // for face cards, use abbreviation { switch (val) { case 11: os << 'J'; break; case 12: os << 'Q'; break; case 13: os << 'K'; break; case 14: os << 'A'; break; } } switch (s) // display suit { case CLUBS: os << "C"; break; case DIAMONDS: os << "D"; break; case HEARTS: os << "H"; break; case SPADES: os << "S"; break; } } int Card::GetVal() const // return the numeric value of a card { return val; } void Card::SetVal(int v) // set the numeric value of a card { val = v; } Suit Card::GetSuit() const // return the suit value of a card { return s; } void Card::SetSuit(Suit st) // set the suit of a card { s = st; } // general utility function for random-number seeding void Randomize() // COMPILER-SPECIFIC: sets the random number generator's seed. { unsigned int seed = unsigned(clock()); srand(seed); } // Deck class member functions Deck::Deck(int num) // constructor for initializing out of "num" standard decks { topCard = 0; // we haven't dealt any cards yet if (num <= 0) num = 1; // set to default if num is bad numCards = num*52; // set number of cards for THIS deck cards = new Card[numCards]; // allocate space for the deck for (int i = 0; i < numCards; i++) // for each card in the deck: { cards[i].SetVal((i % 13) + 2); // assign it a numeric value (2 - 14) switch ((i / 13) % 4) // and a suit. { case 0: cards[i].SetSuit(CLUBS); break; case 1: cards[i].SetSuit(DIAMONDS); break; case 2: cards[i].SetSuit(HEARTS); break; case 3: cards[i].SetSuit(SPADES); break; } } } Deck::~Deck() // final cleanup of dynamic array { delete [] cards; // apply delete to the pointer (to clean up target) } Deck::Deck(const Deck& d) // copy constructor for deep copy { Clone(d); // do the deep copy } Deck& Deck::operator=(const Deck& d) { if (this != &d) // check against self-assignment { delete [] cards; // clean up original array, Clone(d); // do the deep copy } return *this; // return the calling object } void Deck::Clone(const Deck& d) // this is the deep copy basic process, being CALLED by copy constructor // and by assignment operator (so that we only write the code once) { topCard = d.topCard; numCards = d.numCards; cards = new Card[numCards]; // build new array for the new object for (int i = 0; i < numCards; i++) // copy from d's array into this one cards[i] = d.cards[i]; } void Deck::Dump() const // dump contents of member data to screen { cout << "topCard = " << topCard << '\n'; cout << "numCards = " << numCards << '\n'; for (int i = 0; i < numCards; i++) { cards[i].Display(); // Show the card cout << " "; if (i % 13 == 12) cout << '\n'; } cout << "\nThis deck is done\n\n"; } void Deck::Shuffle() // shuffle the deck and set the deal position to the beginning { Randomize(); for (int i = 0; i < 3; i++) // Shuffle 3 times. { for (int j = 0; j < numCards; j++) // Rearrange each card (0 - 51). { int r = rand() % numCards; // Pick a location to swap j-th // card with Card c = cards[j]; cards[j] = cards[r]; cards[r] = c; } } topCard = 0; // no cards dealt yet } void Deck::ShuffleRest() // shuffle the REST of the undealt cards (leaving topCard at same position). { Randomize(); for (int i = 0; i < 3; i++) // Shuffle 3 times. { for (int j = topCard; j < numCards; j++) { // swap j-th card with a random card int r = rand() % (numCards-topCard) + topCard; Card c = cards[j]; cards[j] = cards[r]; cards[r] = c; } } } Card Deck::DealCard() // deal one card from the top of the deck, and return it // NOTE -- NEED to add in error check for exhausted deck. // (and decide on how to handle). { Card deal; deal = cards[topCard]; // next deal position topCard++; // increment deal position return deal; } int Deck::TopCard() const { return topCard; }