

/**
 * The class <code>Deck</code> is a traditional stack meant to hold Cards.
 * File: Deck.java
 * Makes use of package tio
 * Makes use of Debug.class
 * Makes use of Card.class
 * Makes use of MyRand.class
 *
 * @author K Becker
 * @version 1.0 February 2002
 */
public class Deck {
    /** the stack itself */
    private Card [] stack;
    /** 'pointer' to top: index of top card */
    private int top;
    /** size of stack */
    private int max = 52;
    private boolean isfull;
    private boolean isempty;
    /** a JOKER card */
    private Card joker = new Card(Card.JOKER);
    /** an EMPTY card */
    private Card empty = new Card(Card.EMPTY);

/*----------------------------------------------------------------*/
/* ----- constructors ----- */
/** Constructs a new Deck (for 52 cards) - it has NO CARDS in it
 */
public Deck ()
{  // make a standard 52 card deck
	int i;

	stack = new Card[max];
	top = -1;
	isempty = true;
	isfull = false;
	for (i = 0; i < max; i++)
	    stack[i] = null;
}

/** Constructs a new Deck of the size specified - it has NO CARDS in it
 */
public Deck (int size)
{  // make a custom sized deck
	int i;

	stack = new Card[size];
	max = size;
	top = -1;
	isempty = true;
	isfull = false;
	for (i = 0; i < max; i++)
	    stack[i] = null;
}

/** Look at the top card on the deck. Returns empty card if deck empty.
 *  @return reference to top of deck (not a copy)
 */
public Card peek()
{
	if ( isempty )
	    return empty;
	else
	    return stack[ top ];
}

/** Put a new card on the deck. Does nothing if deck full.
 *  @param a reference to an existing card
 */
public void push ( Card value )
{
	if ( isfull ) 
	    return;
	else
	{
		top++;
		stack[top] = value;
		isempty = false;
		if (top == max-1)
		    isfull = true;
		else
		    isfull = false;
	 }
}

/** Take off the top card on the deck.
 *  @return reference to top card of deck (not a copy)
 */
public Card pop ()
{
	if ( isempty )
	    return empty;
	else {
		if (top == 0) // this will make it empty
		    isempty = true;
		else
		    isempty = false;
	}
	isfull = false;
	return stack[ top-- ];
}

/** Access: is the deck full of Cards?
 *  @return true if deck is full.
 */
public boolean isFull()
{
	return isfull;
}

/** Access: is the deck empty?
 *  @return true if deck has no cards.
 */
public boolean isEmpty()
{
	return isempty;
}

/** Load an empty deck with cards FIRST to LAST (0-51)
 */
public void loadDeck()
{ // fill deck with cards, 0-51 only
	for (int i = Card.FIRST; i < max; i++)
		push(new Card(i%(Card.LAST+1)));
}

/** Load an empty deck with cards as given. Array contains
 *  card values. Range 0-15 is forced. If there are fewer
 * cards given than there is room for, they are used again
 * (i.e. duplicates are used).
 * @param cards an integer array containing card numbers
 */
public void loadDeck(int cards[])
{ // fill deck with cards, 0-51 only
	for (int i = 0; i < max; i++)
		push(new Card((cards[i%(cards.length)])%(Card.LAST+1)));
}

/** Shuffle the existing cards in the deck. 
 *  Shuffles only as many as there are.
 */
public void shuffle() 
{ // shuffle the cards in the deck now
	int j,k;
	Card temp;
	for (int i = 0; i < 10000; i++) {
		j = MyRand.choose(0,top);
		k = MyRand.choose(0,top);
		temp = stack[j];
		stack[j] = stack[k];
		stack[k] = temp;
	}
}	    
} // end Deck
