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

  1. #1
    Registered User
    Join Date
    May 2015
    Posts
    228

    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[0].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[0].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[0].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. #2
    Registered User
    Join Date
    Jun 2015
    Posts
    1,643
    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[0] == 2)
    }

  3. #3
    Registered User
    Join Date
    May 2015
    Posts
    228
    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[0].faceValue) != 14))
            {
                return FALSE;
            }
        }
    
    
        return TRUE;
    if there are not consecutive, then it will return false unless the ace is in the beginning.
    Last edited by deathslice; 03-09-2016 at 02:06 PM.

  4. #4
    Registered User
    Join Date
    Jun 2015
    Posts
    1,643
    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[0].faceValue == 2);
    }
    
    int main(void) {
        Card hand[5] = {{2,1},{3,2},{4,1},{5,2},{14,3}};
        printf("%d\n", isStraight(hand, 5));
        return 0;
    }

  5. #5
    Registered User
    Join Date
    May 2015
    Posts
    228
    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 SPADE   "\x06"
    #define CLUB    "\x05"
    #define HEART   "\x03"
    #define DIAMOND "\x04"
    #else
    #define SPADE   "\xE2\x99\xA0"
    #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.
    Last edited by deathslice; 03-09-2016 at 02:34 PM.

  6. #6
    Registered User
    Join Date
    Dec 2015
    Posts
    68
    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[4] == 14){
    if (range for cards [0-3] == 2_to_5)
    else { check any range...

  7. #7
    Registered User
    Join Date
    May 2015
    Posts
    228
    Yes they are sorted and yes as of now I'm only having problems with the ace.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How do i make a class to deal a hand????
    By lilbo4231 in forum C++ Programming
    Replies: 1
    Last Post: 06-29-2011, 11:32 PM
  2. how to sort a player's hand in seven card rummy
    By dex0391 in forum C Programming
    Replies: 4
    Last Post: 06-19-2010, 09:40 PM
  3. Designing a program to deal out seven card stud poker hands
    By killsthehorse in forum C++ Programming
    Replies: 29
    Last Post: 12-08-2008, 04:03 PM
  4. Card shuffle and deal want to put on Stack
    By sugie in forum C++ Programming
    Replies: 4
    Last Post: 12-12-2005, 08:40 PM
  5. what are some other 'life skills' that can go hand in hand with programming
    By Shadow12345 in forum A Brief History of Cprogramming.com
    Replies: 10
    Last Post: 01-17-2003, 02:34 PM