/*
deck.c

A demonstration of arrays as parameters.

This program creates a simulated deck of cards, prints the cards 
in their natural order, shuffles them, prints them out in their 
shuffled order, sorts them, and then prints them out in their 
sorted order.

Ray Ontko 1999/11/02
*/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define DECK_SIZE 52

void init_deck( int deck[] , int size ) ;
void shuffle_deck( int deck[] , int size ) ;
void sort_hand( int hand[] , int size ) ;
void print_hand( int hand[] , int size ) ;
void print_card( int card ) ;

main()
{
  int deck[DECK_SIZE] ;
  int i ;

  srand( time( NULL ) ) ;

  init_deck( deck , DECK_SIZE ) ;
  print_hand( deck , DECK_SIZE ) ;
  putchar( '\n' ) ;

  shuffle_deck( deck , DECK_SIZE ) ;
  print_hand( deck , DECK_SIZE ) ;
  putchar( '\n' ) ;

  sort_hand( deck , DECK_SIZE ) ;
  print_hand( deck , DECK_SIZE ) ;
  putchar( '\n' ) ;
}

void init_deck( int deck[] , int size )
/*
Initializes a deck of unique cards.  Note that this will work 
with any sized deck in which each card is unique (e.g., a 
standard deck, but not for pinochle or euchre decks).
*/
{
  int i ;

  for( i = 0 ; i < size ; i ++ )
    deck[i] = i ;
}

void shuffle_deck( int deck[] , int size )
/*
Shuffles a deck by swapping each card with a random card from the 
deck.  Note that this will work with any sized deck.
*/
{
  int i , j , temp ;

  for( i = 0 ; i < size ; i ++ )
  {
    j = rand() % size ;
    temp = deck[i] ;
    deck[i] = deck[j] ;
    deck[j] = temp ;
  }
}

void sort_hand( int hand[] , int size )
/*
Sorts a hand into increasing order.  This uses an "selection 
sort"; the smallest value is selected and placed into position 0, 
the next smallest is selected and placed into position 1, etc.  
Note that this will work with any sized hand or any style of deck.
*/
{
  int i , j , temp ;

  for( i = 0 ; i < size - 1 ; i ++ )
    for( j = i + 1 ; j < size ; j ++ )
      if( hand[i] > hand[j] )
      {
        temp = hand[i] ;
        hand[i] = hand[j] ;
        hand[j] = temp ;
      }
}

void print_hand( int hand[] , int size ) 
/*
Uses print_card() to print the cards in a hand, one per line.  
Note that this can be used to print any sized hand.  The actual 
print values for the cards are determined by print_card(), so 
this can be used with a variety of card deck styles (standard, 
pinochle, euchre, uno, etc.).
*/
{
  int i ;

  for( i = 0 ; i < size ; i ++ )
  {
    print_card( hand[i] ) ;
    putchar( '\n' ) ;
  }
}

void print_card( int card )
/*
Prints a card from a standard 52 card deck.  Cards 0..12 are 
spades, 13..25 are hearts, 26..38 are diamonds, and 39..51 are 
clubs.  Within each suit, the cards are "Two" through "Ace".
*/
{
  char suit[4][9] = 
    { "Spades" , "Hearts" , "Diamonds" , "Clubs" } ;
  char rank[13][6] = 
    { "Two" , "Three" , "Four" , "Five" , "Six" , "Seven" , "Eight" , 
      "Nine" , "Ten" , "Jack" , "Queen" , "King" , "Ace" } ;
  
  printf( "%s of %s" , rank[card%13] , suit[card/13] ) ;
}
