# Thread: How to deal with the ace card when checking the player's hand

1. ## How to deal with the ace card when checking the player's hand

Before I proceed, I want you to keep in mind that the type of card game that I programming is stud poker.

So right now I have this card structure that hold four datatype

Code:
```struct Card
{
const char *suit;
const char *face;
const int *faceValue; /*This holds the ranking of the face*/
const int *suitValue; /*This holds the ranking of the suit*/
};```
Note: In my ranking of suits, club is the lowest(1), then diamond(2), hearts(3) and finally spade(4).

Next I have my deck structure

Code:
```struct Deck
{
int numOfCards; /*the current number of cards in a deck*/
struct Card card[MAXCARDS]; /*An array of 52 card structure to represent each unique card.*/
};```
Note: Initially ace had a face value of 1 but then I changed it to 14(13 is king basically) because is usually the highest card in any game. Whether it is easier to make the face value of ace a 1 or 14 I simply do not know.

Then finally comes my player structure.

Code:
```enum CardRanking
{
HIGHCARD = 1, PAIR, TWOPAIRS, THREEOFKIND, STRAIGHT,
FLUSH, FULLHOUSE, FOUROFKIND, STRAIGHTFLUSH, ROYALFLUSH
};

struct Players
{
int cardRanking; /*A variable that ranks their hand. 10 being a royal flush and 1 being a high card.*/
struct Card *hand; /*A pointer structure that points to the current cards*/
};```
These four functions are what I use to rank the player's hand

Code:
```int rankHands(struct Card *hand, const int CARDSPERHAND)
{
int numOfPairs = 0, kind = 0, straight = 0, flush = 0;

isFlush(hand, &flush, CARDSPERHAND);
isStraight(hand, &straight, CARDSPERHAND);

if(straight == TRUE && flush == TRUE)
{
return STRAIGHTFLUSH;
}

pairsAndKinds(hand, &numOfPairs, &kind, CARDSPERHAND);

if(kind == FOUROFKIND)
{
return FOUROFKIND;
}
else if(numOfPairs == LENGTHOFPAIR && kind == THREEOFKIND)
{
return FULLHOUSE;
}
else if(flush)
{
return FLUSH;
}
else if(straight)
{
return STRAIGHT;
}
else if(kind == THREEOFKIND)
{
return THREEOFKIND;
}
else if(numOfPairs == LENGTHOFTWOPAIRS)
{
return TWOPAIRS;
}
else if(numOfPairs == LENGTHOFPAIR)
{
return PAIR;
}
else
return HIGHCARD;
}

void isFlush(struct Card *hand, int *flush, const int CARDSPERHAND)
{
int index, isSameSuit = TRUE;
const int *suitRank1 = hand.suitValue;

for(index = 1; index < CARDSPERHAND && isSameSuit; index++)
{
const int *suitRank2 = hand[index].suitValue;

if((*suitRank1) != (*suitRank2))
{
isSameSuit = FALSE;
}
}

if(isSameSuit)
{
*flush = TRUE;
}
}

void isStraight(struct Card *hand, int *straight, const int CARDSPERHAND)
{
int index, isConsecutive = TRUE, gap = 1;
const int *faceRank1 = hand.faceValue;

for(index = 1; index < CARDSPERHAND && isConsecutive; index++, gap++)
{
const int *faceRank2 = hand[index].faceValue;

if((*faceRank1 + gap) != (*faceRank2))
{
isConsecutive = FALSE;
}
}

if(isConsecutive)
{
*straight = TRUE;
}
}

void pairsAndKinds(struct Card *hand, int *numOfPairs, int *kind, const int CARDSPERHAND)
{
int index, counter = 0;
const int *faceRank1 = hand.faceValue;

for(index = 1; index < CARDSPERHAND; index++)
{
const int *faceRank2 = hand[index].faceValue;

if((*faceRank1) == (*faceRank2))
{
counter++;
}
else
{
if(counter == LENGTHOFPAIR)
{
*numOfPairs = *numOfPairs + 1;
}
else if(counter == LENGTHOFTHREE)
{
*kind = THREEOFKIND;
}
else if(counter == LENGTHOFFOUR)
{
*kind = FOUROFKIND;
}

counter = 0;
faceRank1 = hand[index].faceValue;
}
}
}```
Now the main problem is with the ace card. Ace has the possibility of being a low card and a high card. So the way that my straight function works is it checks if the current card + 1 == the next card because the array is sorted prior to doing this. The works fine if we have a high straight(10, 11, 12, 13, 14)(Note: 11 is jack, 12 is queen, 13 is king and 14 is ace). This does not work with a low straight 14 2 3 4 5. As you can see, ace is not plus 1 to the next card.

So what can I do to resolve this dilemma? 2. Your current isStraight routine can be simplified:
Code:
```int isStraight(struct Card *hand, int CARDSPERHAND) {
int i;
for (i = 1; i < CARDSPERHAND; i++)
if (hand[i].faceValue != hand[i - 1].faceValue + 1)
return FALSE;
return TRUE;
}```
To add the ability to count ace as high or low, maybe:
Code:
```int isStraight(struct Card *hand, int CARDSPERHAND) {
int i;
for (i = 1; i < CARDSPERHAND - 1; i++) // don't check last card
if (hand[i].faceValue != hand[i - 1].faceValue + 1)
return FALSE;
return (hand[CARDSPERHAND-1] == hand[CARDSPERHAND-2] + 1)
|| (hand[CARDSPERHAND-1] == 14 && hand == 2)
}``` 3. I 've been thinking about it and your idea almost works except if we have A 2 3 4 5 because 2 does not equal 15(ace has a faceValue of 14).

With that case, the if in the for loop would execute and report that this not a straight when it is.

Maybe I can add this to the if statement:

Code:
```int index;

for(index = 1; index < CARDSPERHAND; index++)
{
if(((*hand[index].faceValue) != (*hand[index - 1].faceValue + 1)) && (*hand.faceValue) != 14))
{
return FALSE;
}
}

return TRUE;```
if there are not consecutive, then it will return false unless the ace is in the beginning. 4. Although I obviously didn't test the code and there are some obvious mistakes in it, the basic algorithm seems to work. Note that the loop doesn't check the last card, which may of course be a 14. This is then tested specially.

BTW, why are faceValue and suitValue pointers? That just wasteful and complicated. I've assumed simple ints below.

Code:
```#include <stdio.h>

typedef enum BOOL {FALSE, TRUE} BOOL;

typedef struct Card {
int faceValue, suitValue;
} Card;

int isStraight(Card *hand, int CARDSPERHAND) {
int i;
for (i = 1; i < CARDSPERHAND - 1; i++) // don't check last card
if (hand[i].faceValue != hand[i - 1].faceValue + 1)
return FALSE;
return (hand[CARDSPERHAND-1].faceValue == hand[CARDSPERHAND-2].faceValue + 1)
|| (hand[CARDSPERHAND-1].faceValue == 14 && hand.faceValue == 2);
}

int main(void) {
Card hand = {{2,1},{3,2},{4,1},{5,2},{14,3}};
printf("%d\n", isStraight(hand, 5));
return 0;
}``` 5. Mostly because my card structure looks like this.

Code:
```struct Card
{
const char *suit;
const char *face;
const int *faceValue;
const int *suitValue;
};```
and they point to these arrays.

Code:
```#if defined(_WIN32) || defined(__MSDOS__)
#define CLUB    "\x05"
#define HEART   "\x03"
#define DIAMOND "\x04"
#else
#define CLUB    "\xE2\x99\xA3"
#define HEART   "\xE2\x99\xA5"
#define DIAMOND "\xE2\x99\xA6"
#endif

const char *suitOfDeck[] = {CLUB, DIAMOND, HEART, SPADE};

const char *faceOfDeck[] = {"Ace", "Two", "Three", "Four", "Five", "Six",
"Seven", "Eight", "Nine", "Ten", "Jack", "Queen",
"King"
};

const int faceValue[] = {14, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
const int suitValue[] = {1, 2, 3, 4};```
If they are not pointers, then I would get a read-only error because they are constants. Essentially they are pointers that point to a const int or char. 6. So the cards are sorted before you call the function?
And it's only in straights you having problems that ace 1 or 14?
So you have 2,3,4,5,14
could do if (card == 14){
if (range for cards [0-3] == 2_to_5)
else { check any range... 7. Yes they are sorted and yes as of now I'm only having problems with the ace. Popular pages Recent additions 