/*** * * Implementation of cards.h. * * Author: Gene Fisher (gfisher@calpoly.edu) * Created: 9may12 * Modified: 9may12 * */ #include "cards.h" int compare_two_cards(Card card1, Card card2) { int face_value1 /* Numeric face value of card 1 */ = compute_face_value(card1); int face_value2 /* Numeric face value of card 2 */ = compute_face_value(card2); /* * If the face value of the cards is the same, return the result of * comparing the suits. */ if (face_value1 == face_value2) { return compute_suit_value(card1) > compute_suit_value(card2); } /* * Otherwise, return the face value comparison. */ return face_value1 > face_value2; } int deal_two_hands(Deck deck, int top, int num_cards, Hand hand1, Hand hand2) { int i1, /* Index for hand1 */ i2; /* Index for hand2 */ /* NOTE: the reason we use two hand indices is * to ensure that the ending blank card is put * in the proper position in the 2nd hand if * the deck runs out between dealing the 1st * and 2nd hands. This is a bit subtle. */ int top_start = top; /* Starting top index, for computing num dealt */ /* * Loop through the deck starting at top and through each hand starting at * 0. Stop when either both hands are fully dealt or top goes past the end * of the deck. */ for (i1 = 0, i2 = 0; (i1 < num_cards) && (top < DECK_SIZE); i1++) { /* * Deal to the 1st hand. */ strcpy(hand1[i1], deck[top]); /* * Increment top to the next card in the deck. */ top++; /* * Deal to the 2nd hand if top is still valid. */ if (top < DECK_SIZE) { strcpy(hand2[i2], deck[top]); i2++; /* * Increment top again, and continue. */ top++; } } /* * Put a blank card into the ending position of each hand. */ strcpy(hand1[i1], BLANK_CARD); strcpy(hand2[i2], BLANK_CARD); /* * Return the number of cards dealt. */ return top - top_start; } void shuffle(Deck unshuffled_deck, Deck shuffled_deck) { int i; /* Loop and array index */ int r; /* Random int between 0 and 51, used as index */ /* to shuffled deck */ /* * Initialize all elements of shuffled deck to blank. */ for (i = 0; i < DECK_SIZE; i++) { strcpy(shuffled_deck[i], BLANK_CARD); } /* * Iterate through the elements of the unshuffled deck, moving each to a * random position in the shuffled deck. */ for (i = 0; i < DECK_SIZE; i++) { /* * Generate a random number r between 0 and 51, such that * shuffled_deck[r] is blank. That is, loop until the chosen number is * the index of a blank element in the shuffled_deck. Note that this * is a "bodiless" for loop, since all of the work is done in the init, * test, and next parts of the loop statement. */ for (r = rand() % DECK_SIZE; strcmp(shuffled_deck[r], BLANK_CARD) != 0; r = rand() % DECK_SIZE) ; /* * Copy the ith unshuffled element to the rth position in the shuffled * deck. */ strcpy(shuffled_deck[r], unshuffled_deck[i]); } } int compute_face_value(Card card) { /* * The only card of string length 3 is a 10. */ if (strlen(card) == 3) { return 10; } /* * If the 1st char of the card string is between 2 and 9, compute its value * with a cute trick. Viz., subtract the value of character '0' from the * char value itself. This will convert the digit character value to its * numeric integer value. The alterative to this trick is an 8-case switch * statement on values '2' through '9' */ if ((card[0] >= '2') && (card[0] <= '9')) { return card[0] - '0'; } /* * If the 1st char of the card string is ace, king, queen, or, jack, make * its face value 14, 13, 12, or 11, respectively. Note the use of the * switch statement here, with returns instead of breaks. */ switch (card[0]) { case 'A': return 14; case 'K': return 13; case 'Q': return 12; case 'J': return 11; } /* * Per the spec, we can assume that a card is well formed, so we should * never get here. In case we do, return 0. */ return 0; } int compute_suit_value(Card card) { int suit_position = strlen(card) - 1; /* * Return an int in the proper suit order. */ switch (card[suit_position]) { case 'S': return 3; case 'H': return 2; case 'D': return 1; case 'C': return 0; } return -1; /* Cannever get here, but gcc doesn't know it */ }