3

I am trying to create a simple poker game Texas Hold'em style with .

At first, I tried to create a deck of cards with 2 char arrays:

char *suits_str[4] = {"Spades", "Hearts", "Diamonds", "Clubs"};
char *faces_str[13] = {"2", "3", "4", "5", "6", "7", "8", "9", "10", 
                       "J", "Q", "K", "A"};

Problem

Everything went well, it was pretty simple to represent the cards. But when it come to analyzing the hands to determine the winner, it seems like using char type values was a pretty bad idea.

So I want to change the data type of the cards into int:

  • Suits: 0="Clubs", 1="Diamonds", 2="Hearts", 3="Spades"
  • Faces: 0="2", 1="3", 11="King", 12="Ace"

Example:

int suits[4] = {0, 1, 2, 3};
int faces[13] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

But now I don't know how to convert those int values back into their matching string values of the cards.

Question

What is the correct and simple approach to represent the cards using int Arrays?

Quan Bui
  • 175
  • 1
  • 13

3 Answers3

6

As you can see from the initializer, you do not need arrays to represent the card values and faces, simple numeric values between resp. 0 and 12 for values and 0 and 3 for faces can be used. To convert to strings, use the card value and face as an index into the arrays suits_str and faces_str:

int suit = 0;   /* spades */
int face = 12;  /* ace */

printf("I am the %s of %s\n", suits_str[suit], faces_str[face]);

You can use enums to make you cade more readable:

enum suits { SPADES, HEARTS, DIAMONDS, CLUBS };
enum faces { DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN,
             JACK, QUEEN, KING, ACE };
int suit = SPADES;
int face = ACE;

printf("I am the %s of %s\n", suits_str[suit], faces_str[face]);

Another idea is to number cards from 0 to 51 and use formulas to extract the face and suit:

int card = rand() % 52;
int suit = card / 13;
int face = card % 13;

printf("I am the %s of %s\n", suits_str[suit], faces_str[face]);

You could create a deck of cards by initializing an array of 52 ints and shuffling it with a simple method:

int deck[52];
for (int i = 0; i < 52; i++) {
     /* start with a sorted deck */
     deck[i] = i;
}

for (int i = 0; i < 1000; i++) {
    /* shuffle by swapping cards pseudo-randomly a 1000 times */
    int from = rand() % 52;
    int to = rand() % 52;
    int card = deck[from];
    deck[from] = deck[to];
    deck[to] = card;
}

printf("Here is a shuffled deck:\n"
for (int i = 0; i < 52; i++) {
     int card = deck[i];
     int suit = card / 13;
     int face = card % 13;
     printf("%s of %s\n", suits_str[suit], faces_str[face]);
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • I am not quite understanding the enums. Why do you have to create int suit = SPADES; int face = ACE; Also, can you the words contain in the enum list? Or they are only for us to know which one is which? – Quan Bui May 08 '16 at 12:44
  • 1
    @JasonBui: enums are useful to create typed names with a numeric value. It is more readable to write `int suit = SPADES;` than to use the numeric value directly as in `int suit = 0;`. The 2 examples are just for illustrative purposes. The last code fragment is a more complete example of how to deal cards for your purpose. – chqrlie May 08 '16 at 18:50
2

The simplest way is to represent each card as single integer:

int getFace(int card) {
    return card/4;
}

int getSuit(int card) {
    return card%4;
}

int createCard(int face, int suit) {
    return face*4+suit;
}

convert them to strings only when showing to user:

void printCard(int card) {
    static char *suits_str[4] = {"Spades", "Hearts", "Diamonds", "Clubs"};
    static char *faces_str[13] = {"2", "3", "4", "5", "6", "7", "8", "9",
              "10", "J", "Q", "K", "A"};
    printf("%s %s\n", faces_str[getFace(card)], suits_str[getSuit(card)]);
}

and do all your computation using integers:

bool isOnePair(int* hand) {
    return getFace(hand[0]) == getFace(hand[1]);
}

bool isFlush(int* hand) {
    return getSuit(hand[0]) == getSuit(hand[1]);
}
Piotr Praszmo
  • 17,928
  • 1
  • 57
  • 65
1

You keep both your created arrays, and use the int array values as indices to your array of pointer to char.

Example:

 int diamonds_index = suits[1];
 char *diamonds_str = suits_str[diamonds_index];
Leandros
  • 16,805
  • 9
  • 69
  • 108