Created
January 2, 2012 21:08
-
-
Save wjlafrance/1552132 to your computer and use it in GitHub Desktop.
Card shuffle
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* | |
* Your tasks are to: | |
* - Create a data representation for the cards (this may require some form of | |
* data structure and suitable constant definitions). | |
* - Create a data representation to keep track of the positions of the cards in | |
* the deck. | |
* - Implement procedures for cutting and shuffling the deck. Each operation | |
* (cut and merge) should include a random perturbation: | |
* - The initial cut might deviate from a perfect cut in half by, say, one to | |
* ten cards. | |
* - Each riffle (merging the cards together) might deviate from a perfect | |
* alternation by, say, one to five cards. | |
* - Create a sorted deck of cards. | |
* - Cut and shuffle the cards using the procedures you implemented. | |
* - Print out the arrangement of cards in the shuffled deck | |
* | |
* | |
* You must write your program in the C programming language. As far as | |
* possible, you should stick to strict ANSI C and use POSIX-compliant library | |
* functions. | |
* Note: Although well-thought-out data representations and algorithms are | |
* obviously important, clarity of expression, readability, and maintainability | |
* by others are also contributing factors in everyday software engineering. | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
enum card_face { | |
ACE = 1, | |
JACK = 11, | |
QUEEN = 12, | |
KING = 13 | |
}; | |
typedef enum card_face e_face; | |
enum card_suit { | |
CLUBS = 0, | |
DIAMONDS = 1, | |
HEARTS = 2, | |
SPADES = 3 | |
}; | |
typedef enum card_suit e_suit; | |
struct card { | |
enum card_face face; | |
enum card_suit suit; | |
}; | |
typedef struct card s_card; | |
/* Function prototypes */ | |
void create_deck(s_card deck[52]); | |
void shuffle_deck(s_card deck[52]); | |
void describe_deck(s_card deck[52]); | |
void describe_card(s_card card); | |
void cut_deck(s_card deck[52], s_card top_half[31], s_card bottom_half[31], int *top_count, int *bottom_count); | |
int main(int argc, char **argv) | |
{ | |
s_card deck[52]; | |
create_deck(deck); | |
/* Shuffle 30 times. Gotta be thorough. */ | |
for(int i = 0; i < 30; i++) { shuffle_deck(deck); } | |
describe_deck(deck); | |
}; | |
void create_deck(s_card deck[52]) | |
{ | |
for (e_suit suit = CLUBS; suit <= SPADES; suit++) { | |
for (enum card_face face = ACE; face <= KING; face++) { | |
deck[suit*13 + face-1].suit = suit; | |
deck[suit*13 + face-1].face = face; | |
} | |
} | |
} | |
void shuffle_deck(s_card deck[52]) | |
{ | |
int top_half_count, bottom_half_count; | |
s_card top_half[31], bottom_half[31]; | |
cut_deck(deck, top_half, bottom_half, &top_half_count, &bottom_half_count); | |
int top_half_i = 0, bottom_half_i = 0; /* positions in each half */ | |
for (int i = 0; i < 52; ) { | |
/* Grab from top half */ | |
if (top_half_i < top_half_count) | |
deck[i++] = top_half[top_half_i++]; | |
/* Roughly 10% chance to grab from top when should come from bottom */ | |
if ((top_half_i < top_half_count) && (arc4random() % 52 <= 3)) | |
deck[i++] = top_half[top_half_i++]; | |
/* Grab from bottom half */ | |
if (bottom_half_i < bottom_half_count) | |
deck[i++] = bottom_half[bottom_half_i++]; | |
/* Roughly 10% chance to grab from bottom when should come from top */ | |
if ((bottom_half_i < bottom_half_count) && (arc4random() % 52 <= 3)) | |
deck[i++] = bottom_half[bottom_half_i++]; | |
} | |
} | |
void cut_deck(s_card deck[52], s_card top_half[31], s_card bottom_half[31], int *top_count, int *bottom_count) | |
{ | |
*top_count = 52/2 + arc4random() % 10 - 5; | |
*bottom_count = 52 - *top_count; | |
for (int i = 0; i < *top_count; i++) { | |
top_half[i] = deck[i]; | |
} | |
for (int i = *top_count; i < 52; i++) { | |
bottom_half[i - *top_count] = deck[i]; | |
} | |
} | |
void describe_deck(s_card deck[52]) | |
{ | |
printf("A: Ace, J: Jack, Q: Queen, K: King\n"); | |
printf("C: Clubs, D: Diamonds, H: Hearts, S: Spades\n"); | |
for (int i = 0; i < 4; i++) { | |
for (int j = 0; j < 13; j++) { | |
describe_card(deck[i*13+j]); | |
} | |
printf("\n"); | |
} | |
} | |
void describe_card(s_card card) | |
{ | |
switch(card.face) { | |
case ACE: printf(" A"); break; | |
case JACK: printf(" J"); break; | |
case QUEEN: printf(" Q"); break; | |
case KING: printf(" K"); break; | |
default: printf(" %2i", card.face); break; | |
} | |
switch(card.suit) { | |
case CLUBS: printf("C"); break; | |
case DIAMONDS: printf("D"); break; | |
case HEARTS: printf("H"); break; | |
case SPADES: printf("S"); break; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment