Code:
#include <stdio.h>
#include <string.h>
#define CARDS_PER_HAND 5
enum { DEALER, PLAYER_1, PLAYER_2, MAX_PLAYERS };
typedef enum { HEARTS, DIAMONDS, CLUBS, SPADES, MAX_SUITS } Suits_t;
typedef enum { F_DUMMY, ACE, DEUCE, THREE, FOUR, FIVE, SIX, SEVEN,
EIGHT, NINE, TEN, JACK, QUEEN, KING, MAX_FACES } Faces_t;
const char *Suits_str[MAX_SUITS] = { "Hearts", "Diamonds", "Clubs", "Spades" };
const char *Faces_str[MAX_FACES] =
{
/*
* The first entry ("Dummy") is not used, it's there to ensure
* that an ACE has the index of 1 in the array.
* This makes things easier when getting data from the user,
* as they can enter 7, and an index of 7 on this array
* gets you "Seven". You may not want to use this method.
*/
"Dummy", "Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven",
"Eight", "Nine", "Ten", "Jack", "Queen", "King"
};
typedef struct Card
{
Faces_t Face;
Suits_t Suit;
} Card_t;
typedef struct Hand
{
Card_t Cards[CARDS_PER_HAND];
} Hand_t;
typedef enum {False, True} Bool_t;
size_t CountSameFace (Hand_t *Hand, Faces_t *Face)
{
/* Returns: The max occurences of a face within a hand.
* The winning face is placed in the variable pointed
* to by parameter Face
*/
static unsigned char Table[MAX_FACES];
unsigned char *Best = Table;
int i;
memset (Table, 0, sizeof (Table));
for (i = 0; i < CARDS_PER_HAND; i++)
{
Faces_t Face;
Face = Hand->Cards[i].Face;
Table[Face]++;
if (Table[Face] > *Best) Best = &Table[Face];
}
*Face = Best - Table;
return *Best;
}
#define TWO_OF_A_KIND(H,C) (CountSameFace((H), (C)) == 2)
#define THREE_OF_A_KIND(H,C) (CountSameFace((H), (C)) == 3)
#define FOUR_OF_A_KIND(H,C) (CountSameFace((H), (C)) == 4)
int main(void)
{
Hand_t Hands[MAX_PLAYERS];
Faces_t WinningFace;
size_t MatchingFaces;
/*
* Populate a hand manually.
* This wouldn't normally be done like this.
*/
Hands[PLAYER_1].Cards[0].Face = ACE;
Hands[PLAYER_1].Cards[0].Suit = HEARTS;
Hands[PLAYER_1].Cards[1].Face = KING;
Hands[PLAYER_1].Cards[1].Suit = DIAMONDS;
Hands[PLAYER_1].Cards[2].Face = SEVEN;
Hands[PLAYER_1].Cards[2].Suit = CLUBS;
Hands[PLAYER_1].Cards[3].Face = ACE;
Hands[PLAYER_1].Cards[3].Suit = DIAMONDS;
Hands[PLAYER_1].Cards[4].Face = ACE;
Hands[PLAYER_1].Cards[4].Suit = SPADES;
/* Now look for an "X of a kind" winner */
if ((MatchingFaces = CountSameFace (&Hands[PLAYER_1], &WinningFace)) > 1)
printf ("You have %d of a kind, for face %s\n", MatchingFaces, Faces_str[WinningFace]);
else puts ("Looser");
/* An example using the macros: */
if (THREE_OF_A_KIND(&Hands[PLAYER_1], &WinningFace))
{
printf ("(via the macro)-> Player %d has three of a kind for face %s\n",
PLAYER_1, Faces_str[WinningFace]);
}
return(0);
}
/*
My output
You have 3 of a kind, for face Ace
(via the macro)-> Player 1 has three of a kind for face Ace
*/