//******************************************************************
// 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 // 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);
}
}