Pick a Card, Any Card

Last week’s Lesson discussed how to monitor random numbers by using an array: When a random value is drawn, it’s corresponding array element is incremented. By continuing that same thought, you can easily ensure that the same random number isn’t used when programming a card game. But first, the game itself!

To program a card game you need to create a virtual deck. That’s actually kind of easy:

int deck[52];

Ta-da!

Of course, it would help if you coded a method to properly interpret those array elements as cards. If you don’t, you’d have a tough time convincing users who play your Video Poker game that 0, 13, 18, 31 and 42 is a winning hand.

To remedy the situation, I offer this code. It takes values 0 through 51 — which humans would read as 1 through 52 or cards in a deck — and displays the corresponding card value:

#include <stdio.h>

#define CARDS 52

void showcard(int card);

int main()
{
    int x;

    for(x=0;x<CARDS;x++)
    {
        showcard(x);
    }

    return(0);
}

/* Take values 0 through 51 (cards in a deck) and display
   corresponding card name */
void showcard(int card)
{
    char *suit[4] = { "Spades", "Hearts", "Clubs", "Diamonds" };

    switch(card%13)
    {
        case 0:
            printf("%2s","A");
            break;
        case 10:
            printf("%2s","J");
            break;
        case 11:
            printf("%2s","Q");
            break;
        case 12:
            printf("%2s","K");
            break;
        default:
            printf("%2d",card%13+1);
    }
    printf(" of %s\n",suit[card/13]);
}

In this code, a for loop at Line 11 plows through values 0 through 51, equal to the 52 cards in a deck. The action takes place with the showcard() function at Line 21. A switch-case structure pulls out references to the Ace, Jack, Queen, and King so that they’re displayed as letters. Two spaces (%2s) are used to display each to keep the output lined up. Other cards are displayed as a value in Line 40. Two spaces are used (%2d) so that the 10 lines up. The card%13+1 operation is used to ensure that the numbers displayed range from 2 through 10.

Finally, at Line 42, the suit is displayed.

So far, the code merely plays 52 Card Pickup (albeit an orderly version). To make the code a game, an element of randomness is required.

The following modification to the code displays 5 random card values:

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

#define CARDS 52
#define DRAW 5

void showcard(int card);

int main()
{
    int x,c;

    srand((unsigned)time(NULL));
    for(x=0;x<DRAW;x++)
    {
        c = rand() % CARDS;
        showcard(c);
    }

    return(0);
}

/* Take values 0 through 51 (cards in a deck) and display
   corresponding card name */
void showcard(int card)
{
    char *suit[4] = { "Spades", "Hearts", "Clubs", "Diamonds" };

    switch(card%13)
    {
        case 0:
            printf("%2s","A");
            break;
        case 10:
            printf("%2s","J");
            break;
        case 11:
            printf("%2s","Q");
            break;
        case 12:
            printf("%2s","K");
            break;
        default:
            printf("%2d",card%13+1);
            printf("%2d",card%13+1);
    }
    printf(" of %s\n",suit[card/13]);
}

The above code contains only a few modifications from the original: New header files are included at Lines 2 and 3 so that the random number generation routines can be used. The constant DRAW is declared, representing the number of cards to randomly draw. The srand() function at Line 14 and rand() at Line 17 help to draw the random cards.

Here’s what I see for output:

A of Spades
9 of Hearts
Q of Diamonds
Q of Hearts
7 of Hearts

Not bad! I got a pair. But after running the code a few times, I saw this:

6 of Hearts
9 of Hearts
K of Diamonds
9 of Hearts
K of Hearts

Wow! Being able to draw the 9 of Hearts twice is some trick!

You can employ a number of techniques to prevent a card from being drawn twice. One of the most versatile is to create an array that represents the deck of cards. The values in that array help you keep track of which cards have been drawn and which have not. I’ll explore those possibilities next week.

Leave a Reply