// Deck.m
// Project: Cribbage
// Stephan Wacker
// 93-09-16

#import "deck.h"
#import "cribbage.h"

#import "Deck.h"
#import "Player.h"
#import "ComputerPlayer.h"
#import "Table.h"
#import "LocalizableStrings.h"

@implementation Deck


- makedeck
//
// initialize a deck of cards to contain one of each type
//
{
    // Collect cards.
    [human emptyHand];
    [comp emptyHand];
    [table empty];
    [table hideCard: starter];
    
    makedeck( deck );
    nCards = CARDS;
    nCrib = 0;
    
    [table downCard: starter];	// folded deck
    
    return self;
}




- shuffle
//
// given a deck of cards, shuffle it -- i.e. randomize it
// see Knuth, vol. 2, page 125
//
{
    register  int	j, k;
    CARD		c;

    for( j = nCards; j > 0; --j )  {
	k = ( rand() >> 4 ) % j;	/* random 0 <= k < j */
	c = deck[j - 1];		/* exchange (j - 1) and k */
	deck[j - 1] = deck[k];
	deck[k] = c;
    }
    
    return self;
}



- (CARD) getCard
//
// select a random card from the deck and remove it
//
{
    int		i;
    CARD	result;
    
    i = (rand() >> 4) % nCards;		/* random cut */
    result = deck[i];
    
    remove_card( result, deck, nCards );
    -- nCards;
    
    return result;
}


- cut
{
    turnover = [self getCard];
    [table upCard: starter card: turnover];
    
    strcpy( local_buf, [nondealer pronoun] );
    strcat( local_buf, quiet ? " cut " : " cut the " );
    addmsg( LOCAL_BUF );
    msgcard(turnover, FALSE);
    addmsg( CUT_POSTFIX );
    endmsg();
    
    if (turnover.rank == JACK) {
	strcpy( local_buf, [dealer pronoun] );
	strcat( local_buf, " get two for his heels" );
	addmsg( LOCAL_BUF );
	endmsg();
	[dealer peg: 2];
    }
    
    [comp makeknown: &turnover num: 1];
    
    return self;
}



- (CARD) nextCard
//
// get the first card from the deck and remove it
//
{
    int		i;
    CARD	result;
    
    i = 0;
    result = deck[i];
    
    remove_card( result, deck, nCards );
    -- nCards;
    
    return result;
}



- setDealer: aPlayer
{
    if( aPlayer ) {
	dealer = aPlayer;
    } else {
	dealer = nondealer;
    }
    nondealer = (dealer == human ? comp : human);
    
    return self;
}


- dealer
{
    return dealer;
}


- nondealer
{
    return nondealer;
}


- (BOOL) isCompCrib
{
    return (dealer == comp);
}



- deal
//
// Deal cards to both players from deck.
//
{
    int		i;
    
    for( i = 0; i < FULLHAND; i++ ) {
	[nondealer dealCard: [self nextCard]];
	[dealer    dealCard: [self nextCard]];
    }
    
    [human sortHand];
    [comp sortHand];
    
    return self;
}


- putIntoCrib: (CARD) aCard
{
    if( nCrib == 0 ) {
	[table downCard: [dealer cardInCrib]];
    }
    crib[ nCrib++ ] = aCard;
    
    return self;
}


- (CARD *) getCrib
{
    [table hideCard: [dealer cardInCrib]];
    return crib;
}


- (CARD) turnover
{
    return turnover;
}


@end	// Deck
