//****************************************************************** // IMPLEMENTATION FILE (carddeck.cpp) // This file implements the CardDeck class member functions. // The CardPile class is a public base class of CardDeck //****************************************************************** #include "carddeck.h" #include <cstdlib> // For rand() using namespace std; const int HALF_DECK = 26; // Additional private members of class (beyond those // inherited from CardPile): // void Merge( CardPile&, CardPile& ); Used by the Shuffle // function //****************************************************************** CardDeck::CardDeck() // Constructor--creates a list of DECK_SIZE components representing // a standard deck of playing cards // Postcondition: // After empty linked list created (via implicit call to base // class constructor), all DECK_SIZE playing cards have been // inserted into deck in order by suit and by rank { int count; // Loop counter CardType tempCard; // Temporary card tempCard.suit = CLUB; tempCard.rank = 1; InsertTop(tempCard); // Loop to create balance of deck for (count = 2; count <= DECK_SIZE; count++) { // Increment rank tempCard.rank++; // Test for change of suit if (tempCard.rank > 13) { tempCard.suit = Suits(tempCard.suit + 1); tempCard.rank = 1; } InsertTop(tempCard); } } //****************************************************************** void CardDeck::Shuffle( /* in */ int numberOfShuffles ) // Rearranges the deck (the list of DECK_SIZE components) into a // different order. The list is divided into two parts, which are // then merged. The process is repeated numberOfShuffles times // Precondition: // Length of deck == DECK_SIZE // && numberOfShuffles is assigned // Postcondition: // The order of components in the deck has been rearranged // numberOfShuffles times, randomly { CardType tempCard; // Temporary card int count1; // Loop counter int count2; // Loop counter int sizeOfCut; // Size of simulated cut for (count1 = 1; count1 <= numberOfShuffles; count1++) { CardPile halfA; // Half of the list, initially empty CardPile halfB; // Half of the list, initially empty sizeOfCut = rand() % DECK_SIZE + 1; // Divide deck into two parts for (count2 = 1; count2 <= sizeOfCut; count2++) { RemoveTop(tempCard); halfA.InsertTop(tempCard); } for (count2 = sizeOfCut+1; count2 <= DECK_SIZE; count2++) { RemoveTop(tempCard); halfB.InsertTop(tempCard); } if (sizeOfCut <= HALF_DECK) Merge(halfA, halfB); else Merge(halfB, halfA); } } //****************************************************************** void CardDeck::Merge( /* inout */ CardPile& shorterList, /* inout */ CardPile& longerList ) // Merges shorterList and longerList into deck // Precondition: // Length of shorterList > 0 && Length of longerList > 0 // && Length of deck == 0 // Postcondition: // Deck is the list of cards obtained by merging // shorterList@entry and longerList@entry into one list // && Length of shorterList == 0 // && Length of longerList == 0 { CardType tempCard; // Temporary card // Take one card from each list alternately while (shorterList.Length() > 0) { shorterList.RemoveTop(tempCard); InsertTop(tempCard); longerList.RemoveTop(tempCard); InsertTop(tempCard); } // Copy remainder of longer list to deck while (longerList.Length() > 0) { longerList.RemoveTop(tempCard); InsertTop(tempCard); } } //****************************************************************** void CardDeck::Recreate( /* inout */ CardPile& pile1, /* inout */ CardPile& pile2 ) // Gathers cards from two piles and puts them back into deck // Precondition: // Length of deck == 0 // && (Length of pile1 + length of pile2) == DECK_SIZE // Postcondition: // Deck is the list consisting of all cards from pile1@entry // followed by all cards from pile2@entry // && Length of deck == DECK_SIZE // && Length of pile1 == 0 && Length of pile2 == 0 { CardType tempCard; // Temporary card while (pile1.Length() > 0) { pile1.RemoveTop(tempCard); InsertTop(tempCard); } while (pile2.Length() > 0) { pile2.RemoveTop(tempCard); InsertTop(tempCard); } }