Finding a 'straight' in poker.

This is a discussion on Finding a 'straight' in poker. within the C Programming forums, part of the General Programming Boards category; Originally Posted by anon In addition your O(n!) or whatever complexity and gazillion nested loops are reduced nicely to O(n). ...

  1. #31
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Quote Originally Posted by anon View Post

    In addition your O(n!) or whatever complexity and gazillion nested loops are reduced nicely to O(n).
    Yes I guess those nested loops are actually another 'hidden' loop with an index of 5, which
    is one pass for each card. But it was easy to write it as I did probaly easier than putting
    another loop in. But I will have a go at that too,it probably won't look as 'pretty' though.

  2. #32
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,059
    That does not seem to work at all.
    All you are doing is seting the first 7 cards to ace
    then counting the number you set and seeing if
    still 7, which it is unsurprisingly.
    iIndex is the rank of the card. For instance if iIndex == 11, a queen, then the following would indicate that you have one queen in your hand;
    Code:
    Rank[iIndex]++;
    Incrementing it again, as follows would indicate that you have two queens in your hand
    Code:
    Rank[iIndex]++;
    So, what is actually stored in the array at the index is the number of cards in your hand for a particular face card. It's not the rank as in ace thru king. The index number is actually the rank.

    This code is from a complete poker sample

  3. #33
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Now a question to you: how would you make your code work if the number of cards was a run-time variable (seeing that 7 is non-standard anyway) so the user could choose how many cards to play with?

    Hint: it may be possible with recursion.

    Edit:
    BobS0327 - yes, that's a much more clever way to represent the hand for evaluation!
    Last edited by anon; 01-08-2008 at 03:56 PM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #34
    Registered User whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    7,762
    My idea was to first check for pairs, and then, if there were none, check for "connectors," (a card of the next highest or lowest rank) Assuming that every card has a chance to be a pivot, and every pivot has a connector, then the hand should be a straight.

    Here's an implementation where I assume the deck is just a bunch of integers from 0 to 51:
    Code:
    int compare_cards ( const void * pa, const void * pb ) 
    {
        const int * a = pa;
        const int * b = pb;
    
        return *a < *b ? -1 : *a > *b ? +1 : 0;
    }
    int has_pairs ( int hand[], size_t handsiz )
    {
        size_t card;
        int pairs = 0;
        int * hand_aux = malloc ( sizeof hand[0] * handsiz );
    
        for ( card = 0; card < handsiz; card++ ) {
            hand_aux[card] = hand[card];
        }
        qsort( hand_aux, handsiz, sizeof hand[0], compare_cards );
        for ( card = 1; card < handsiz; card++ ) {
            pairs += hand[card] / 13 == hand[card-1] / 13;
        }
        free( hand_aux );
        hand_aux = NULL;
        return pairs;
    }
    int straights ( int hand[], size_t handsiz )
    {
        int conseq;
        size_t card, pivot;
    
        if ( has_pairs( hand, handsiz ) ) return 0;
    
        for ( pivot = 0; pivot < handsiz; pivot++ ) {
            conseq = 0;
            for ( card = 0; card < handsiz; card++ ) {
                conseq += hand[pivot] / 13 + 1 == hand[card] || hand[pivot] / 13 - 1 == hand[card];
            }
            if ( conseq == 0 ) break;
        }
        return pivot == handsiz;
    }
    Last edited by whiteflags; 01-08-2008 at 05:45 PM.

  5. #35
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Quote Originally Posted by BobS0327 View Post
    iIndex is the rank of the card. For instance if iIndex == 11, a queen, then the following would indicate that you have one queen in your hand;
    Code:
    Rank[iIndex]++;
    Incrementing it again, as follows would indicate that you have two queens in your hand
    Code:
    Rank[iIndex]++;
    So, what is actually stored in the array at the index is the number of cards in your hand for a particular face card. It's not the rank as in ace thru king. The index number is actually the rank.

    This code is from a complete poker sample

    Yes that is for finding cards of the same value eg 777, which pretty simple,
    finding 34567 in 8743Q56 is a little trickier.

  6. #36
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,059
    Yes that is for finding cards of the same value eg 777, which pretty simple,
    finding 34567 in 8743Q56 is a little trickier.
    Naaw. No big deal. Modified code below:

    Code:
    #include <stdio.h>
    
    #define NUMBER_OF_FACES 13
    #define CARDS_IN_HAND 7
    #define CARDS_NEEDED_FOR_STRAIGHT 5
    int Rank[NUMBER_OF_FACES];
    
    void CheckForStraight(void)
    {
        int iNumberConsecutive = 0;
        int iRank  = 0;
        while (Rank[iRank] == 0) iRank++;
        for (; iRank < NUMBER_OF_FACES && Rank[iRank]; iRank++)
            iNumberConsecutive++;
        if (iNumberConsecutive >= CARDS_NEEDED_FOR_STRAIGHT)        
        printf("Straight up!\n");
        else printf("NO straight!\n");
    }
    
    int main(void)
    {
        // Where iIndex is rank (face) value,  
        // Zero is an ace, 1 is a deuce, 2 is trey... 12 is a king
        Rank[8]++;  // nine face card
        Rank[7]++;  // eight face card
        Rank[4]++;  // five  face card
        Rank[3]++;  // four face card
        Rank[11]++; // queen face card
        Rank[5]++;  // six face card
        Rank[6]++;  // seven face card
    
        CheckForStraight();
    
        return 0;
    }

  7. #37
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    This seems to work.

    Code:
    /* straight.c */
    
    #define MAXN        13
    #define CARDSINHAND  7
    #define IN_A_ROW     5
    
    int is_straight( int* cards, int ncards ) {
    
        int seen[ MAXN ];
        int in_a_row;
        int i;
    
        for (i = 0; i < MAXN; i++) seen[ i ] = 0;    /* zero "seen" array */
    
        for (i = 0; i < ncards; i++)                 /* set values seen to non-zero */
            seen[ cards[ i ] - 1 ]++;
    
        in_a_row = 0;                                /* see if there are IN_A_ROW in a row */
        for (i = 0; i < MAXN; i++) {
            if (seen[ i ]) {
                if (++in_a_row >= IN_A_ROW)
                    return 1;
            }
            else
                in_a_row = 0;
        }
        return 0;
    }
    
    int main() {
        int c[] = { 4, 6, 3, 5, 7, 9, 11 };
        int d[] = { 4, 6, 2, 5, 7, 9, 11 };
        printf( "c: " );
        printf( is_straight( c, CARDSINHAND ) ? "yes" : "no" );
        printf( "\nd: " );
        printf( is_straight( d, CARDSINHAND ) ? "yes" : "no" );
        printf( "\n" );
    }

  8. #38
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Quote Originally Posted by oogabooga View Post
    This seems to work.

    Code:
    /* straight.c */
    
    #define MAXN        13
    #define CARDSINHAND  7
    #define IN_A_ROW     5
    
    int is_straight( int* cards, int ncards ) {
    
        int seen[ MAXN ];
        int in_a_row;
        int i;
    
        for (i = 0; i < MAXN; i++) seen[ i ] = 0;    /* zero "seen" array */
    
        for (i = 0; i < ncards; i++)                 /* set values seen to non-zero */
            seen[ cards[ i ] - 1 ]++;
    
        in_a_row = 0;                                /* see if there are IN_A_ROW in a row */
        for (i = 0; i < MAXN; i++) {
            if (seen[ i ]) {
                if (++in_a_row >= IN_A_ROW)
                    return 1;
            }
            else
                in_a_row = 0;
        }
        return 0;
    }
    
    int main() {
        int c[] = { 4, 6, 3, 5, 7, 9, 11 };
        int d[] = { 4, 6, 2, 5, 7, 9, 11 };
        printf( "c: " );
        printf( is_straight( c, CARDSINHAND ) ? "yes" : "no" );
        printf( "\nd: " );
        printf( is_straight( d, CARDSINHAND ) ? "yes" : "no" );
        printf( "\n" );
    }
    Yes it does work!!
    That is a very clever way of doing it.
    It avoids any sorting and it must be the fastest way of doing it too.
    It took me a while to figure out what you were doing but it suddenly dawned on me.
    You just set flag if a card is present and then look for 5 flags in a row.

    I don't think it picks up 10,11,12,13,1 though (10,J,Q,K,A)
    However if you change
    Code:
       if (++in_a_row >= IN_A_ROW)
    to
    Code:
       if ( (++in_a_row >= IN_A_ROW) || ( (i==MAXN-1) && seen[0]==1)  )
    I think it does. (assuming I have not introduced a bug!)
    I never thought of doing it like that, well done.

  9. #39
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Of course you might like to get rid of all those nasty local variables!!
    Code:
    /* straight.c */
    #include <stdio.h>
    #define MAXN        13
    #define CARDSINHAND  7
    #define IN_A_ROW     5
    int c[] = { 4, 6, 3, 5, 7, 9, 11 };
    int d[] = { 4, 1, 12, 13, 10, 2, 11 };
    int *ptr;
    int buf[13];
    int in_a_row;
    int x,i;
    count(){
    	in_a_row = 0;  
    	for (x=0; x<MAXN ; x++)	buf[x]=0;                        //clear buffer
    	for (x=0; x<CARDSINHAND; x++) buf[ptr[x]-1]=1; //set flag for cards found
    	for (i = 0; i < MAXN; i++) {                                     //see if there are IN_A_ROW in a row 
            if (buf[ i ]) {
                 	if (     (++in_a_row >= IN_A_ROW)||  ( (i==MAXN-1) && buf[0]==1)   ) 
                        return 1;
                    }
                    else  in_a_row = 0;
            }
            return 0;
    }
    int main() {
        ptr=c;
        printf( "c: " );
        printf( count() ? "yes" : "no" );
        ptr=d;
        printf( "\nd: " );
        printf( count() ? "yes" : "no" );
        printf( "\n" );
    }
    Now to me that looks easier to follow and less complex and is probably what I would
    have done if I had thought of the method myself. Although I might have passed
    the pointer to the function. Might not have returned a value though

  10. #40
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,438
    Different version of the game have different numbers of cards in the hand, (don't they?) i dunno, i don't remember, i only ever play the ubiquitous(?) texas hold em now.
    Hey Esbo, i know all those odds calculators are out there, but if you just used published programs there'd be no will to write anything of your own would there!?
    Maybe you or anyone that fancies it could try writing one that just shows how often in holdem you are likely to get a pair dealt in the community cards, say with five players at table (i.e. 10 cards dealt already)
    This is one thing that really cracks me up and i always think i am being cheated when it seems to happen a lot haha! because you know you are sitting on nice pair of kings, then a flamin 2comes out on the river to make a pair in the community cards an you just know some turkey that stayed in hopin, has another crummy two an is now holdin three, man that kills me haha!
    i doubt i am being cheated of course, its just hard luck, but i started writing a routine to prove it but got distracted with something else in the end, i don't think i fully finished it.
    Another version is how likely that one of the other players is holding a third or fourth card,

  11. #41
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    I don't think it picks up 10,11,12,13,1 though (10,J,Q,K,A)
    Well spotted!
    It now counts ace as both low and high. (Note MAXN is now 14.
    I also (believe I) fixed another bug in the for(i=MAXN-1... line
    by making the test a little more complex.

    I definitely agree that
    for (i = 0; i < MAXN; i++)
    is simpler, and it's how I first did it.
    But in optimizing, I realized that it does not actually
    need to scan to the end (all MAXN positions of cards)
    if there is no chance of a straight (not enough cards
    left compared to in_a_row). Unfortunately, this required
    basically doing it backwards.
    It's one of those balance issues between easier to understand
    and slightly faster. Usually I go for easier to understand,
    but I assumed you were looking for the fastest way.

    I'll stay out of the political "globals vs locals" debate,
    except to mention that 8 out of 10 programmers agree that the
    use of locals discourages terrorism.

    Code:
    /* straight.c */
    
    #define MAXN        14  /* 13 cards plus an extra space for ace high */
    #define CARDSINHAND  7
    #define IN_A_ROW     5
    
    int is_straight( int* cards, int ncards ) {
    
        int seen[ MAXN ];
        int in_a_row;
        int i;
    
        for (i = 0; i < MAXN; i++) seen[ i ] = 0;
    
        for (i = 0; i < ncards; i++) {
            seen[ cards[ i ] - 1 ]++;
            if (cards[ i ] == 1) seen[ MAXN - 1 ]++; /* Set ace as high also */
        }
    
        in_a_row = IN_A_ROW;
        for (i = MAXN - 1; i + 1 >= in_a_row; i--) {
            if (seen[ i ]) {
                if (--in_a_row == 0)
                    return 1;
            }
            else
                in_a_row = IN_A_ROW;
        }
        return 0;
    }
    
    int main() {
        int c[] = {  1,  3,  2,  9,  5,  4, 11 };  /* 1,  2,  3,  4,  5,  9, 11 */
        int d[] = { 11,  1,  3, 13,  7,  9,  5 };  /* 1,  3,  5,  7,  9, 11, 13 */
        int e[] = {  5, 12, 10,  7,  1, 11, 13 };  /* 1,  5,  7, 10, 11, 12, 13 */
        int f[] = { 12,  5, 11,  6, 10,  8,  7 };  /* 5,  6,  7,  8, 10, 11, 12 */
        printf( "c: " );   printf( is_straight( c, CARDSINHAND ) ? "yes" : "no" );
        printf( "\nd: " ); printf( is_straight( d, CARDSINHAND ) ? "yes" : "no" );
        printf( "\ne: " ); printf( is_straight( e, CARDSINHAND ) ? "yes" : "no" );
        printf( "\nf: " ); printf( is_straight( f, CARDSINHAND ) ? "yes" : "no" );
        printf( "\n" );
    }

  12. #42
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Quote Originally Posted by rogster001 View Post
    Different version of the game have different numbers of cards in the hand, (don't they?) i dunno, i don't remember, i only ever play the ubiquitous(?) texas hold em now.
    Hey Esbo, i know all those odds calculators are out there, but if you just used published programs there'd be no will to write anything of your own would there!?
    Maybe you or anyone that fancies it could try writing one that just shows how often in holdem you are likely to get a pair dealt in the community cards, say with five players at table (i.e. 10 cards dealt already)
    This is one thing that really cracks me up and i always think i am being cheated when it seems to happen a lot haha! because you know you are sitting on nice pair of kings, then a flamin 2comes out on the river to make a pair in the community cards an you just know some turkey that stayed in hopin, has another crummy two an is now holdin three, man that kills me haha!
    i doubt i am being cheated of course, its just hard luck, but i started writing a routine to prove it but got distracted with something else in the end, i don't think i fully finished it.
    Another version is how likely that one of the other players is holding a third or fourth card,

    Yes there are several variates of poker, there is also stud poker where you get
    dealt 7 cards alll to your self but its still 7 cards in total.
    The there is Omaha where you get dealt 4 cards and the there are 5 'community'
    cards, however you can only use 2 of your 4 card and indeed you must use 2 unlilke
    Texas where you can just use 1 or even none (just use the 5 community cards).

    So the Omaha variation would be even trickier. I guess you could just run the
    search for each of the 6 possible pairs or run it once with all nine cards and then
    check 2 'pocket' cards are used.

    You should get a pair every 17 hands. The first card is irrelvant there are then 3 cards
    which it can pair with, so that is 3 in 51 or 1 in 17, a nice round number. Trouble is they are
    a bit like buses, you wait for ages and then a load appear in a run. Typically when you have KK someone will have AA!!


    I always suspect there is likely to be cheating but it is probably unfounded but there was a case at Absolute Poker where a guy who worked there could see other people cards.

    http://www.google.com/search?q=potri...B_enGB210GB210
    I once checked I was getting my fair share of pocket cards but I never looked at straights
    or flushes. It would take a fair bit of work to do it and it wuld not prove all was legitimate anyway as its a complex game.

  13. #43
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Exactly. You get a pair every 17 hands, which is another way of saying
    don't wait for the bus! But how often do they show up at the table, in
    anybody's hand?

    As for the odds of a pair in the community cards, that is simply the
    odds of a pair in any 3 random cards, so to get a sense for it you
    could shuffle a pack of cards and take off three-card packets
    one by one. By the calculation below, you should get a pair almost
    1 out of every 5 times (specifically, 17%).
    Code:
    Number of possible 3-card combinations:
      n = 52 * 51 * 50 = 132600
    Number of possible 3-card combinations _without_ a pair:
      m = 52 * 48 * 44 = 109824
    Probability of 3-card combination not having a pair:
      m / n     = 0.8282
    So probability of 3-card combination having a pair:
      1 - m / n = 0.1718

  14. #44
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Quote Originally Posted by oogabooga View Post
    Exactly. You get a pair every 17 hands, which is another way of saying
    don't wait for the bus! But how often do they show up at the table, in
    anybody's hand?

    As for the odds of a pair in the community cards, that is simply the
    odds of a pair in any 3 random cards, so to get a sense for it you
    could shuffle a pack of cards and take off three-card packets
    one by one. By the calculation below, you should get a pair almost
    1 out of every 5 times (specifically, 17%).
    Code:
    Number of possible 3-card combinations:
      n = 52 * 51 * 50 = 132600
    Number of possible 3-card combinations _without_ a pair:
      m = 52 * 48 * 44 = 109824
    Probability of 3-card combination not having a pair:
      m / n     = 0.8282
    So probability of 3-card combination having a pair:
      1 - m / n = 0.1717647
    I usually do rough calculations for such things.
    I would have have said there are 3 ways of 3 of a kind 110, 101, and 011
    All of which are 17-1.
    However this gives 0.1764706 which is close to your figure but not spot on.
    Then I was thinking 3 of a kind would explain the difference, however it came
    to twice the difference (or half I forget) so I had to think it through properly.

    I do not think 110 is 1 in 17 it is 1/17X 48/50 (the last card cannot be the same) which is 0.0564706 which times 3 is 0.1694118 which gives a difference of 0.0023529.
    3 of a kind is 1/17X1/25 which is also 0.0023529!!!
    Glad that worked!! (I amended your rounded figure above) (1 - m / n = 0.1717647).


    I am glad you put that in because it made me realise my way of doing things was slightly wrong.

    I have been trying to figure out the chance of 'flopping a straight' but it seems rather
    complicated!!

    However I will have a go say hold 67, the cards you need are 8 9 10 or 5 8 9 or 4 5 8 or 3 4 5 that is (4 ways), but....they can be in any order eg 3 4 5 or 3 5 4 or 4 3 5 or 4 5 3 or or 5 3 4 or 5 4 3. (6 ways).

    So.. one single way if 4/50X4/49X 4/48=0.0005442 so times by 6 and 4 = 0.0130612
    Which is 1 in 76.56.

    Now to look up the correct answer on the net (it seems in the right 'ball park')


    http://www.flopturnriver.com/Common-Flop-Odds.html



    "flopping a straight (including the slight chance of a straight flush in some cases) 1.306%"!!
    Which is the same as 0.0130612.

    Well I am pleasantly surprised that was correct!!!

    Well thats given me a bit more confidence in doing those sort of calculations now.

    When I play online I just do very rough calculations for example if I have 4 cards to
    a flush with two to come I say it is 5-1 (0.2).There are 9 'outs' left and about 47 in the pack
    so thats 9/47= 0.1912. However usually you have 2 cards to come so I say I have 2 in 5
    chance. Mind you there are other matters to consider such as what your opponent has, or
    whether the cards seem to be running against you. Sometimes you just know your will lose!
    There is always a guy at the table who just seem to win all the time!!

  15. #45
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    In a previous post I gave the probability for a pair in 3 cards,
    but that's just the flop. As shown below, for all 5 community cards
    the odds are basically 50/50, so that's why you see so many pairs
    on the table!
    Code:
    Number of possible 5-card combinations:
      n = 52 * 51 * 50 * 49 * 48 = 311875200
    Number of possible 5-card combinations _without_ a pair:
      m = 52 * 48 * 44 * 40 * 36 = 158146560
    Probability of 5-card combination not having a pair:
      m / n     = 0.5051
    So probability of 5-card combination having a pair:
      1 - m / n = 0.4929

Page 3 of 4 FirstFirst 1234 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Making a Poker Game
    By krazyxazn in forum C Programming
    Replies: 4
    Last Post: 04-07-2009, 07:45 PM
  2. Help!For poker game simulation
    By tx1988 in forum C++ Programming
    Replies: 24
    Last Post: 05-25-2007, 10:59 PM
  3. Poker bad beats
    By PJYelton in forum A Brief History of Cprogramming.com
    Replies: 21
    Last Post: 01-15-2005, 11:42 PM
  4. MFC :: Finding Child Window of a CWnd* Object?
    By SyntaxBubble in forum Windows Programming
    Replies: 2
    Last Post: 09-06-2003, 10:06 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21