Shuffle

A.First Edition
This is my first edition of assignment of shuffle which is quite different from what I write by myself before 
which is a dealing program.
B.The problem
The problem is to use the methods specified in the base abstract class List which implemented in two derived class
---AList, LList. They are array-based and linklist-based implementation class. 
กก
C.The idea of program
//program features:
//1. The header file given by book has one problem, that is, the AList.h and LList.h
//	 both has a "DefaultListSize" as default parameter for constructor which is not
//	 defined in their abastract base class----List. So, I arbitrarily add 
//	 const int DefaultListSize = 52 in List.h.
//2. In order for a better representation, I defined a helper class "Card" which stores 
//	 the suit and value information of a card. Since the List "print" function will use
//	 "cout<<element" to printout element. This Card class has implement a friend function
//	 to overload operator <<. And because I use pointer "Card*" instead of object "Card"
//	 as element in AList and LList, I have to overload "ostream& operator<<(ostream&, Card*)".
//3. Shuffle is the major class to handle shuffling. Its private data includes both AList and
//	 LList lists. Basically I need to four lists to do shuffling:
//		a) a source list, which stores the original data to be shuffled.
//		b) a target list, which stores the result data.
//		c) one left and one right list to store the left and right half of source list.
//	 Since AList and LList are all inherited from List, I can use base class pointer to 
//	 do the same job. So I also need four pointer of List:
//		a) a pointer pointing to source list---pSource;
//		b) a pointer pointing to target list---pTarget;
//		c) two pointer pointing to left and right list---pLeft, pRight;
//4. Within the Shuffle there is a Card array cards[52] which stores all 52 cards. The List
//	 don't have to store the Card object itself, instead store its pointer Card*. So my AList
//	 and LList is of type of AList<Card*> and LList<Card*>. Suppose this element Card is a 
//	 complicated class with many data inside, its pointer will be much lighter to store.
//5. In the main function, I simply pass a flag to indicate whether I need to use array-based
//	 List or LinkList-based List implementation to function "shuffling(ListType theType);". 
//	 All other code don't have to modify and it will output almost same with different List
//	 implementation to indicate that my program is implementation independent! So, the input
//	 of program is as simple as changing a single parameter in main function and call the 
//	 function "shuffling" again which will automatically initialize and doShuffle.
//6. function "shuffling" will call function "doShuffle" several times before it initialize 
//	 all parameters and divide the original source list into "left" and "right" by copying.
//7. function "doShuffle" is using base class pointer, so it is totally List-implementation-
//	 independent which means the code is uniform disregarding the type of List.
/////////////////////////////////////////////////////////////////////////////////////////////
D.The major functions
C.Further improvement
กก
//List.h The base abstract class
#ifndef LIST_H
#define LIST_H
// List abstract class
const int DefaultListSize=52;
template <class Elem> class List {
public:
  // Reinitialize the list.  The client is responsible for
  // reclaiming the storage used by the list elements.
  virtual void clear() = 0;
  // Insert an element at the front of the right partition.
  // Return true if successful, false if the list is full.
  virtual bool insert(const Elem&) = 0;
  // Append an element at the end of the right partition.
  // Return true if successful, false if the list is full.
  virtual bool append(const Elem&) = 0;
  // Remove the first element of right partition. Return
  // true if successful, false if right partition is empty.
  // The element removed is returned in the parameter.
  virtual bool remove(Elem&) = 0;
  // Place fence at list start, making left partition empty
  virtual void setStart() = 0;
  // Place fence at list end, making right partition empty
  virtual void setEnd() = 0;
  // Move fence one step left; no change if already at start
  virtual void prev() = 0;
  // Move fence one step right; no change if already at end
  virtual void next() = 0;
  // Return length of left partition
  virtual int leftLength() const = 0;
  // Return length of right partition
  virtual int rightLength() const = 0;
  // If pos or more elements are in the list, set the size
  // of left partition to pos and return true.  Otherwise,
  // do nothing and return false.
  virtual bool setPos(int pos) = 0;
  // Return in first parameter the first element  of the
  // right partition.  Return true if successful, false
  // if the right partition is empty.
  virtual bool getValue(Elem&) const = 0;
  // Print the contents of the list
  virtual void print() const = 0;
};

#endif
กก
//AList.h  The array-based derived class
#ifndef ALIST_H
#define ALIST_H

// This is the file to include in your code if you want access to the
// complete AList template class

// First, get the declaration for the base list class
#include "list.h"

template <class Elem> // Array-based list implementation
class AList : public List<Elem> {
private:
  int maxSize;        // Maximum size of list
  int listSize;       // Actual number of elements in list
  int fence;          // Position of fence
  Elem* listArray;    // Array holding list elements
public:
  AList(int size=DefaultListSize) { // Constructor
    maxSize = size;
    listSize = fence = 0;
    listArray = new Elem[maxSize];
  }
  ~AList() { delete [] listArray; } // Destructor
  void clear() {
    delete [] listArray;
    listSize = fence = 0;
    listArray = new Elem[maxSize];
  }
  bool insert(const Elem&);
  bool append(const Elem&);
  bool remove(Elem&);
  void setStart() { fence = 0; }
  void setEnd()   { fence = listSize; }
  void prev()     { if (fence != 0) fence--; }
  void next()     { if (fence <= listSize) fence++; }
  int leftLength() const  { return fence; }
  int rightLength() const { return listSize - fence; }
  bool setPos(int pos) {
    if ((pos >= 0) && (pos <= listSize)) fence = pos;
    return (pos >= 0) && (pos <= listSize);
  }
  bool getValue(Elem& it) const {
    if (rightLength() == 0) return false;
    else { it = listArray[fence]; return true; }
  }
  void print() const {
    int temp = 0;
    cout << "< ";
    while (temp < fence) cout << listArray[temp++] << " ";
    cout << "| ";
    while (temp<listSize) cout << listArray[temp++] << " ";
    cout << ">\n";
  }
};

template <class Elem> // Insert at front of right partition
bool AList<Elem>::insert(const Elem& item) {
  if (listSize == maxSize) return false; // List is full
  for(int i=listSize; i>fence; i--)      // Shift Elems up
    listArray[i] = listArray[i-1];       //   to make room
  listArray[fence] = item;
  listSize++;                       // Increment list size
  return true;
}

template <class Elem> // Append Elem to end of the list
bool AList<Elem>::append(const Elem& item) {
  if (listSize == maxSize) return false;
  listArray[listSize++] = item;
  return true;
}

// Remove and return first Elem in right partition
template <class Elem> bool AList<Elem>::remove(Elem& it) {
  if (rightLength() == 0) return false; // Nothing in right
  it = listArray[fence];                // Copy removed Elem
  for(int i=fence; i<listSize-1; i++)   // Shift them down
    listArray[i] = listArray[i+1];
  listSize--;                           // Decrement size
  return true;
}

#endif
//Link.h  A helper class for linklist
#ifndef LINK_H
#define LINK_H

// Singly-linked list node
template <class Elem> class Link {
public:
  Elem element;      // Value for this node
  Link *next;        // Pointer to next node in list
  Link(const Elem& elemval, Link* nextval =NULL)
    { element = elemval;  next = nextval; }
  Link(Link* nextval =NULL) { next = nextval; }
};
#endif
//LList.h Linklist-based derived class
#ifndef LLIST_H
#define LLIST_H

// This is the file to include in your code if you want access to the
// complete LList template class

// First, get the declaration for the base list class
#include "list.h"

// Linked list implementation
template <class Elem> class LList: public List<Elem> {
private:
  Link<Elem>* head;       // Pointer to list header
  Link<Elem>* tail;       // Pointer to last Elem in list 
  Link<Elem>* fence;      // Last element on left side
  int leftcnt;            // Size of left partition
  int rightcnt;           // Size of right partition
  void init() {           // Intialization routine
    fence = tail = head = new Link<Elem>;
    leftcnt = rightcnt = 0;
  }
  void removeall() {   // Return link nodes to free store
    while(head != NULL) {
      fence = head;
      head = head->next;
      delete fence;
    }
  }
public:
  LList(int size=DefaultListSize) { init(); }
  ~LList() { removeall(); }  // Destructor
  void clear() { removeall(); init(); }
  bool insert(const Elem&);
  bool append(const Elem&);
  bool remove(Elem&);
  void setStart()
    { fence = head; rightcnt += leftcnt; leftcnt = 0; }
  void setEnd()
    { fence = tail; leftcnt += rightcnt; rightcnt = 0; }
  void prev();
  void next() {
    if (fence != tail) // Don't move fence if right empty
      { fence = fence->next; rightcnt--; leftcnt++; }
  }
  int leftLength() const  { return leftcnt; }
  int rightLength() const { return rightcnt; }
  bool setPos(int pos);
  bool getValue(Elem& it) const {
    if(rightLength() == 0) return false;
    it = fence->next->element;
    return true;
  }
  void print() const;
};

template <class Elem> // Insert at front of right partition
bool LList<Elem>::insert(const Elem& item) {
  fence->next = new Link<Elem>(item, fence->next);  
  if (tail == fence) tail = fence->next;  // New tail
  rightcnt++;
  return true;
}

template <class Elem> // Append Elem to end of the list
bool LList<Elem>::append(const Elem& item) {
  tail = tail->next = new Link<Elem>(item, NULL);
  rightcnt++;
  return true;
}

// Remove and return first Elem in right partition
template <class Elem> bool LList<Elem>::remove(Elem& it) {
  if (fence->next == NULL) return false; // Empty right
  it = fence->next->element;       // Remember value
  Link<Elem>* ltemp = fence->next; // Remember link node
  fence->next = ltemp->next;       // Remove from list
  if (tail == ltemp) tail = fence; // Reset tail
  delete ltemp;                    // Reclaim space
  rightcnt--;
  return true;
}

// Move fence one step left; no change if left is empty
template <class Elem> void LList<Elem>::prev() {
  Link<Elem>* temp = head;
  if (fence == head) return; // No previous Elem
  while (temp->next!=fence) temp=temp->next;
  fence = temp;
  leftcnt--; rightcnt++;
}

// Set the size of left partition to pos
template <class Elem> bool LList<Elem>::setPos(int pos) {
  if ((pos < 0) || (pos > rightcnt+leftcnt)) return false;
  fence = head;
  for(int i=0; i<pos; i++) fence = fence->next;
  return true;
}

template <class Elem> void LList<Elem>::print() const {
  Link<Elem>* temp = head;
  cout << "< ";
  while (temp != fence) {
    cout << temp->next->element << " ";
    temp = temp->next;
  }
  cout << "| ";
  while (temp->next != NULL) {
    cout << temp->next->element << " ";
    temp = temp->next;
  }
  cout << ">\n";
}

#endif
//Shuffle.cpp  The implementation of shuffle class and driver program
//////////////////////////////////////////////////////
//program Name: Shuffle for assignment 2 of comp352 //
//file name: Shuffle.cpp                            //
//author: Qingzhe Huang                             //
//ID: 5037735                                       //
//date: Oct. 5, 2003                                //
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//program features:
//1. The header file given by book has one problem, that is, the AList.h and LList.h
//	 both has a "DefaultListSize" as default parameter for constructor which is not
//	 defined in their abastract base class----List. So, I arbitrarily add 
//	 const int DefaultListSize = 52 in List.h.
//2. In order for a better representation, I defined a helper class "Card" which stores 
//	 the suit and value information of a card. Since the List "print" function will use
//	 "cout<<element" to printout element. This Card class has implement a friend function
//	 to overload operator <<. And because I use pointer "Card*" instead of object "Card"
//	 as element in AList and LList, I have to overload "ostream& operator<<(ostream&, Card*)".
//3. Shuffle is the major class to handle shuffling. Its private data includes both AList and
//	 LList lists. Basically I need to four lists to do shuffling:
//		a) a source list, which stores the original data to be shuffled.
//		b) a target list, which stores the result data.
//		c) one left and one right list to store the left and right half of source list.
//	 Since AList and LList are all inherited from List, I can use base class pointer to 
//	 do the same job. So I also need four pointer of List:
//		a) a pointer pointing to source list---pSource;
//		b) a pointer pointing to target list---pTarget;
//		c) two pointer pointing to left and right list---pLeft, pRight;
//4. Within the Shuffle there is a Card array cards[52] which stores all 52 cards. The List
//	 don't have to store the Card object itself, instead store its pointer Card*. So my AList
//	 and LList is of type of AList<Card*> and LList<Card*>. Suppose this element Card is a 
//	 complicated class with many data inside, its pointer will be much lighter to store.
//5. In the main function, I simply pass a flag to indicate whether I need to use array-based
//	 List or LinkList-based List implementation to function "shuffling(ListType theType);". 
//	 All other code don't have to modify and it will output almost same with different List
//	 implementation to indicate that my program is implementation independent! So, the input
//	 of program is as simple as changing a single parameter in main function and call the 
//	 function "shuffling" again which will automatically initialize and doShuffle.
//6. function "shuffling" will call function "doShuffle" several times before it initialize 
//	 all parameters and divide the original source list into "left" and "right" by copying.
//7. function "doShuffle" is using base class pointer, so it is totally List-implementation-
//	 independent which means the code is uniform disregarding the type of List.
/////////////////////////////////////////////////////////////////////////////////////////////



#include <iostream>
#include "LIST.H"
#include "ALIST.H"
#include "LINK.H"
#include "LLIST.H"

using namespace std;

char* suitStr[4] = { "Spade", "Heart", "Diamond", "Club"};

enum SuitName
{Spade, Heart, Diamond, Club};

enum ListType
{ArrayList, LinkList};

enum Position
{Left, Right};

//a helper class to denote the card value and suit
class Card
{
	//Card overload "<<" operator,
	// otherwise List member function "print" won't work!
	//PLS note the second parameter is pointer of Card: "Card*"
	friend ostream& operator<<(ostream& out, Card* card)
	{
		switch (card->value)
		{
		case 14:
			out<<"Ace";
			break;
		case 13:
			out<<"King";
			break;
		case 12:
			out<<"Queen";
			break;
		case 11:
			out<<"Jack";
			break;
		default:
			out<<card->value;
			break;
		}
		out<<" "<<suitStr[card->suit];
		return out;
	}
	
private:
	int suit;
	int value;
public:
	void setSuit(int theSuit) { suit = theSuit;}
	void setValue(int theValue) { value = theValue;}

};


class Shuffle
{
private:
	//this is the real card array and its pointers will be 
	//given to our List class
	Card cards[4][13];
	//these two generic base class pointer will do the same job
	//disregarding the implementation of array or linklist based.
	List<Card*>* pSource;
	List<Card*>* pTarget;
	//these two pointer represents the left-half and right-half
	List<Card*>* pLeft;
	List<Card*>* pRight;
	//array-based list
	//these are the left-half, right-half list
	AList<Card*> aLeft;
	AList<Card*> aRight;
	//these are the source and target list(array)
	AList<Card*> aSource;
	AList<Card*> aTarget;
	//link-list based list
	//these are the left-half, right-half list
	LList<Card*> lLeft;
	LList<Card*> lRight;
	//these are the source and target list(Linklist)
	LList<Card*> lSource;
	LList<Card*> lTarget;
	//param "pos" indicate whether remove from left or right,
	//return true if can remove, otherwise false
	bool getCard(Position pos);
	int getRand();
	void doShuffle(bool toShow=false);
	void initialize(ListType theType);
	void setParam(ListType theType);
	void divideList();
public:
	void shuffling(ListType theType=ArrayList);

};

int main()
{
	Shuffle S;
	cout<<"First use array-based List to shuffle:\n";
	S.shuffling();
	cout<<"\n\n\nSecond use linklist-based List to shuffle:\n\n";
	S.shuffling(LinkList);
	cout<<endl;
	return 0;
}

//param "pos" indicate whether remove from left or right,
//return true if can remove, otherwise false
bool Shuffle::getCard(Position pos)
{
	Card* card;//a pointer
	int number = getRand();
	List<Card*>* temp = pos==Left?pLeft:pRight;
	for (int i=0; i<number; i++)
	{
		//remove one from left or right and 
		//insert into target
		if (temp->remove(card))
		{
			pTarget->insert(card);
		}
		else
		{
			return false;
		}
	}
	return true;
}

//divide source list into two halves and copy
//them into "left" and "right"
void Shuffle::divideList()
{
	Card* card;
	pSource->setPos(26);
	pLeft->setStart();
	pRight->setStart();
	while (pSource->remove(card))
	{
		//remove is from beginning, so we need append 
		pRight->append(card);
	}
	pSource->setStart();
	while (pSource->remove(card))
	{
		//append is efficient than insert generally
		pLeft->append(card);
	}
}

//this set up the pointers by param of ListType which
//indicate whether it is array or linklist
void Shuffle::setParam(ListType theType)
{
	switch (theType)
	{
	case ArrayList:
		pLeft = &aLeft;
		pRight = &aRight;
		pSource = &aSource;
		pTarget = &aTarget;
		break;
	case LinkList:
		pLeft = &lLeft;
		pRight = &lRight;
		pSource = &lSource;
		pTarget = &lTarget;
		break;
	}
}



//this function do the shuffle job, it first initialize 
//source according parameter "ListType"; Then shuffle 5 times
//in first time, call "doShuffle" with param of "true" to ask
//"doShuffle" to print intermidiate result.
void Shuffle::shuffling(ListType theType)
{
	List<Card*>* temp;
	initialize(theType);
	for (int i=0; i<5; i++)
	{
		cout<<"\nbefore no."<<i+1<<" times shuffle:\n";
		pSource->print();
		if (i==0)
		{
			doShuffle(true);
		}
		else
		{
			doShuffle(false);
		}
		cout<<"\nafter no."<<i+1<<" times shuffle:\n";
		pTarget->print();
		//swap the two pointer so that shuffle again.
		temp = pSource;
		pSource= pTarget;
		pTarget = temp;
	}
}

//a utility method to get random number of 0-5
int Shuffle::getRand()
{
	return rand()%6;
}

//first divide source into two halves, copy them to pLeft and pRight
//alternatively remove random number of cards from two halves until both
//halves are empty
void Shuffle::doShuffle(bool toShow)
{
	bool leftEmpty=false, rightEmpty=false;
	int counter=0;
	divideList();
	if (toShow)
	{
		cout<<"\nbefore getCard, left half is:\n";
		pLeft->print();
		cout<<"\nbefore getCard, right half is:\n";
		pRight->print();
		cout<<"\nbefore getCard, result is:\n";
		pTarget->print();
	}
	while ((!leftEmpty)||(!rightEmpty))
	{
		if (!getCard(Left))
		{
			leftEmpty= true;
		}
		if (!getCard(Right))
		{
			rightEmpty = true;
		}
		counter++;
		if (toShow)
		{
			cout<<"\nafter "<<counter<<" times getCard, left half is:\n";
			pLeft->print();
			cout<<"\nafter "<<counter<<" times getCard, right half is:\n";
			pRight->print();
			cout<<"\nafter "<<counter<<" times getCard, result is:\n";
			pTarget->print();
		}
	}	
}
		
//initialize cards array and copy the standard card pointers into source.
void Shuffle::initialize(ListType theType)
{
	setParam(theType);
	for (int theSuit =0; theSuit<4; theSuit++)
	{
		for (int theValue=0; theValue<13; theValue++)
		{
			cards[theSuit][theValue].setSuit(theSuit);
			//the value of a card is starting from 14 till 2
			cards[theSuit][theValue].setValue(14-theValue);
			//as the element is Card*, we add pointers
			//and here the pSource is actually a base class pointer
			//disregarding it is array-based-list or link-list-based-list!
			pSource->append(&cards[theSuit][theValue]);
		}
	}
}





กก
The result is like following:
I omitted all intermediate result as it is too many, if you really like to check, click here.
......

after no.1 times shuffle:

< | 2 Club 3 Club 4 Club 5 Club 6 Club 7 Club 8 Club 9 Club 10 Club Jack Club Queen Club 2 Heart King Club Ace Club 2 Diamond 3 Diamond 3 Heart 4 Heart 5 Heart 4 Diamond 5 Diamond 6 Diamond 7 Diamond 8 Diamond 6 Heart 7 Heart 8 Heart 9 Heart 10 Heart Jack Heart Queen Heart King Heart Ace Heart 2 Spade 3 Spade 4 Spade 5 Spade 6 Spade 7 Spade 8 Spade 9 Spade 9 Diamond 10 Diamond Jack Diamond 10 Spade Jack Spade Queen Spade King Spade Ace Spade Queen Diamond King Diamond Ace Diamond >


before no.2 times shuffle:

< | 2 Club 3 Club 4 Club 5 Club 6 Club 7 Club 8 Club 9 Club 10 Club Jack Club Queen Club 2 Heart King Club Ace Club 2 Diamond 3 Diamond 3 Heart 4 Heart 5 Heart 4 Diamond 5 Diamond 6 Diamond 7 Diamond 8 Diamond 6 Heart 7 Heart 8 Heart 9 Heart 10 Heart Jack Heart Queen Heart King Heart Ace Heart 2 Spade 3 Spade 4 Spade 5 Spade 6 Spade 7 Spade 8 Spade 9 Spade 9 Diamond 10 Diamond Jack Diamond 10 Spade Jack Spade Queen Spade King Spade Ace Spade Queen Diamond King Diamond Ace Diamond >


after no.2 times shuffle:

< | 7 Heart 6 Heart 8 Diamond 7 Diamond 6 Diamond 5 Diamond 4 Diamond 5 Heart Ace Diamond 4 Heart King Diamond Queen Diamond Ace Spade King Spade Queen Spade 3 Heart 3 Diamond 2 Diamond Ace Club King Club Jack Spade 10 Spade Jack Diamond 2 Heart Queen Club Jack Club 10 Diamond 9 Diamond 9 Spade 8 Spade 7 Spade 10 Club 6 Spade 5 Spade 4 Spade 9 Club 3 Spade 2 Spade Ace Heart King Heart Queen Heart 8 Club 7 Club 6 Club Jack Heart 10 Heart 9 Heart 8 Heart 5 Club 4 Club 3 Club 2 Club >


before no.3 times shuffle:

< | 7 Heart 6 Heart 8 Diamond 7 Diamond 6 Diamond 5 Diamond 4 Diamond 5 Heart Ace Diamond 4 Heart King Diamond Queen Diamond Ace Spade King Spade Queen Spade 3 Heart 3 Diamond 2 Diamond Ace Club King Club Jack Spade 10 Spade Jack Diamond 2 Heart Queen Club Jack Club 10 Diamond 9 Diamond 9 Spade 8 Spade 7 Spade 10 Club 6 Spade 5 Spade 4 Spade 9 Club 3 Spade 2 Spade Ace Heart King Heart Queen Heart 8 Club 7 Club 6 Club Jack Heart 10 Heart 9 Heart 8 Heart 5 Club 4 Club 3 Club 2 Club >


after no.3 times shuffle:

< | Jack Club Queen Club 2 Heart Jack Diamond 10 Spade Jack Spade King Club Ace Club 2 Diamond 3 Diamond 3 Heart Queen Spade King Spade Ace Spade Queen Diamond King Diamond 2 Club 4 Heart 3 Club 4 Club 5 Club Ace Diamond 5 Heart 8 Heart 9 Heart 10 Heart Jack Heart 6 Club 7 Club 8 Club Queen Heart King Heart Ace Heart 4 Diamond 5 Diamond 6 Diamond 7 Diamond 2 Spade 3 Spade 9 Club 4 Spade 5 Spade 6 Spade 10 Club 7 Spade 8 Spade 9 Spade 9 Diamond 10 Diamond 8 Diamond 6 Heart 7 Heart >


before no.4 times shuffle:

< | Jack Club Queen Club 2 Heart Jack Diamond 10 Spade Jack Spade King Club Ace Club 2 Diamond 3 Diamond 3 Heart Queen Spade King Spade Ace Spade Queen Diamond King Diamond 2 Club 4 Heart 3 Club 4 Club 5 Club Ace Diamond 5 Heart 8 Heart 9 Heart 10 Heart Jack Heart 6 Club 7 Club 8 Club Queen Heart King Heart Ace Heart 4 Diamond 5 Diamond 6 Diamond 7 Diamond 2 Spade 3 Spade 9 Club 4 Spade 5 Spade 6 Spade 10 Club 7 Spade 8 Spade 9 Spade 9 Diamond 10 Diamond 8 Diamond 6 Heart 7 Heart >


after no.4 times shuffle:

< | 10 Heart 9 Heart 8 Heart 5 Heart Ace Diamond 5 Club 7 Heart 6 Heart 4 Club 3 Club 8 Diamond 10 Diamond 9 Diamond 4 Heart 2 Club King Diamond Queen Diamond 9 Spade 8 Spade Ace Spade 7 Spade 10 Club 6 Spade 5 Spade 4 Spade King Spade Queen Spade 9 Club 3 Spade 2 Spade 3 Heart 3 Diamond 2 Diamond Ace Club King Club 7 Diamond 6 Diamond Jack Spade 10 Spade Jack Diamond 2 Heart Queen Club 5 Diamond 4 Diamond Ace Heart King Heart Jack Club Queen Heart 8 Club 7 Club 6 Club Jack Heart >


before no.5 times shuffle:

< | 10 Heart 9 Heart 8 Heart 5 Heart Ace Diamond 5 Club 7 Heart 6 Heart 4 Club 3 Club 8 Diamond 10 Diamond 9 Diamond 4 Heart 2 Club King Diamond Queen Diamond 9 Spade 8 Spade Ace Spade 7 Spade 10 Club 6 Spade 5 Spade 4 Spade King Spade Queen Spade 9 Club 3 Spade 2 Spade 3 Heart 3 Diamond 2 Diamond Ace Club King Club 7 Diamond 6 Diamond Jack Spade 10 Spade Jack Diamond 2 Heart Queen Club 5 Diamond 4 Diamond Ace Heart King Heart Jack Club Queen Heart 8 Club 7 Club 6 Club Jack Heart >


after no.5 times shuffle:

< | King Spade 4 Spade 5 Spade 6 Spade 10 Club Jack Heart 6 Club 7 Club 8 Club 7 Spade Ace Spade Queen Heart Jack Club King Heart Ace Heart 8 Spade 9 Spade Queen Diamond King Diamond 4 Diamond 2 Club 5 Diamond Queen Club 4 Heart 9 Diamond 10 Diamond 8 Diamond 3 Club 2 Heart Jack Diamond 10 Spade Jack Spade 6 Diamond 4 Club 6 Heart 7 Diamond King Club 7 Heart 5 Club Ace Club 2 Diamond 3 Diamond 3 Heart 2 Spade Ace Diamond 5 Heart 8 Heart 9 Heart 3 Spade 9 Club Queen Spade 10 Heart >




                                 back.gif (341 bytes)       up.gif (335 bytes)         next.gif (337 bytes)