Today is: 8 January, 2012
Check todays hot topics

Card Shuffler in C

There are a lot of card shuffling examples out there, I guess to show examples of rand(). 20 minutes and some ghetto code later, here is one with card structures defined. It takes one argument, which is the number of decks you want to shuffle. Read the code to learn more.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
 
struct card {
    char sname;
    char lname[12];
    char suit[12];
};
 
char snames[14] = "A23456789TJQK\0";
 
char *lnames[14] = {
    "Ace",
    "Two",
    "Three",
    "Four",
    "Five",
    "Six",
    "Seven",
    "Eight",
    "Nine",
    "Ten",
    "Jack",
    "Queen",
    "King",
    NULL
};
 
char *suits[5] = {
    "Clubs",
    "Diamonds",
    "Hearts",
    "Spades",
    NULL
};
 
struct card *initcards(int num);
int shufflecards(struct card *c, unsigned int count);
unsigned int leeroy(unsigned char *key, unsigned int len);
 
int main( int argc, char **argv )
{
    unsigned short int decks, cards;
    struct card *c;
    int i = 0;
 
    if (argc != 2)
        return -1;
 
    decks = atoi(argv[1]);
    cards = decks*52;
 
    printf("initializing %d deck(s) of %d cards ...\n", decks, cards);
    c = initcards(cards);
    printf("%d cards shuffled ...\n", i = shufflecards(c, cards));
 
    for (i = 0; i < cards; i++)
    {
        printf("[%c%c]\n",
                c[i].sname, c[i].suit[0]);
    }
 
    free(c);
    return 0;
}
 
struct card *initcards(int num)
{
    struct card *c;
    int j, n, s;
    c = malloc(num * sizeof(struct card));
 
    for (j = n = s = 0; j < num; j++, n++, s++)
    {
        if (s == 4) s = 0;
        if (n == 13) n = 0;
 
        c[j].sname = snames[n];
        strcpy(c[j].lname, lnames[n]);
        strcpy(c[j].suit, suits[s]);
    }
 
    return c;
}
 
int shufflecards(struct card *c, unsigned int count)
{
    time_t now;
    unsigned int seed, i;
 
    time(&now);
    seed = leeroy((unsigned char *) &now, sizeof(time_t));
    srand(seed);
 
    for (i = 0; i < count; i++)
    {
        unsigned int x;
        struct card tmp;
 
        x = (i+rand()/(RAND_MAX + 1.0) * (count - i));
/*
        printf("%c(%c) <==> %c(%c)\n", c[i].sname, c[i].suit[0],
                c[x].sname, c[x].suit[0]);
*/
        tmp  = c[i];
        c[i] = c[x];
        c[x] = tmp;
    }
 
    return i;
}
 
unsigned int leeroy(unsigned char *key, unsigned int len)
{
    unsigned int hash=0;
    unsigned int i;
 
    for (i=0; i<len; ++i)
    {
        hash+=key[i];
        hash+=(hash<<10);
        hash^=(hash>>6);
    }
 
    hash+=(hash<<3);
    hash^=(hash>>11);
    hash+=(hash<<15);
    return hash;
}