Skip to content

Instantly share code, notes, and snippets.

@wjlafrance
Created January 2, 2012 21:08
Show Gist options
  • Save wjlafrance/1552132 to your computer and use it in GitHub Desktop.
Save wjlafrance/1552132 to your computer and use it in GitHub Desktop.
Card shuffle
/*
*
* 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