HandRank EvaluateHand(int hand[5]) { int rankcount[13]= {0}; for (int i=0; i< 5; i++) rankcount[RANK(hand[i])]++; if (is_royal(hand)) return eRoyal; if (is_straight_flush(hand, rankcount)) return eStraightFlush; if (is_four(rankcount)) return eFour; if (is_full(rankcount)) return eFull; if (is_flush(hand)) return eFlush; if (is_straight(rankcount)) return eStraight; if (is_three(rankcount)) return eThree; if (is_TwoPair(rankcount)) return eTwoPair; if (is_Pair(rankcount)) return ePair; return eBust; }
static void determine_hand(struct hand *const best_hand, const unsigned long long HAND){ enum hand_t type = HIGH_CARD; const unsigned CLUB = HAND & 0x1FFF; const unsigned DIAMOND = HAND>>13 & 0x1FFF; const unsigned HEART = HAND>>26 & 0x1FFF; const unsigned SPADE = HAND>>39 & 0x1FFF; const unsigned CLUB_ACED = CLUB | (CLUB & 0x1) << 13; const unsigned DIAMOND_ACED = DIAMOND | (DIAMOND & 0x1) << 13; const unsigned HEART_ACED = HEART | (HEART & 0x1) << 13; const unsigned SPADE_ACED = SPADE | (SPADE & 0x1) << 13; const unsigned LUMP = CLUB_ACED | DIAMOND_ACED | HEART_ACED | SPADE_ACED; unsigned rank; for(unsigned i = 0; i < 10; i++){ const unsigned SMASK = 0x3E00 >> i; // check for straight if(is_straight(LUMP, SMASK)){ // check for straight-flush if(is_straight_flush(CLUB_ACED, DIAMOND_ACED, HEART_ACED, SPADE_ACED, SMASK)){ type = STRAIGHT_FLUSH; }else{ type = STRAIGHT; } rank = 9 - i; break; } } const unsigned CLUB_NORMALIZED = CLUB_ACED >> 1; const unsigned DIAMOND_NORMALIZED = DIAMOND_ACED >> 1; const unsigned HEART_NORMALIZED = HEART_ACED >> 1; const unsigned SPADE_NORMALIZED = SPADE_ACED >> 1; const unsigned LUMP_NORMALIZED = LUMP >> 1; unsigned pairs = 0; unsigned triplet = 0; unsigned quadruplet = 0; unsigned chits = 0; unsigned dhits = 0; unsigned hhits = 0; unsigned shits = 0; for(unsigned i = 0; type < FOUR_OF_A_KIND && i < 13; i++){ const unsigned C = CLUB_NORMALIZED & 1<<i; const unsigned D = DIAMOND_NORMALIZED & 1<<i; const unsigned H = HEART_NORMALIZED & 1<<i; const unsigned S = SPADE_NORMALIZED & 1<<i; const unsigned C_HIT = (C > 0); const unsigned D_HIT = (D > 0); const unsigned H_HIT = (H > 0); const unsigned S_HIT = (S > 0); switch(C_HIT + D_HIT + H_HIT + S_HIT){ case 4: quadruplet = 1<<i; type = FOUR_OF_A_KIND; continue; case 3: triplet = 1<<i; if(type < THREE_OF_A_KIND){ type = THREE_OF_A_KIND; } case 2: pairs |= 1<<i; if(type < ONE_PAIR){ type = ONE_PAIR; } break; } chits += C_HIT; dhits += D_HIT; hhits += H_HIT; shits += S_HIT; } unsigned suit; // check for full-house, flush, and two pair if(type < FULL_HOUSE && is_full_house(triplet, &pairs)){ type = FULL_HOUSE; }else if(type < FLUSH && (suit = is_flush(chits, dhits, hhits, shits))){ switch(suit){ case 1: rank = CLUB_NORMALIZED; break; case 2: rank = DIAMOND_NORMALIZED; break; case 3: rank = HEART_NORMALIZED; break; case 4: rank = SPADE_NORMALIZED; break; } type = FLUSH; }else if(type < TWO_PAIR && is_two_pair(&pairs)){ type = TWO_PAIR; } switch(type){ case HIGH_CARD: rank = find_extrema(LUMP_NORMALIZED, 5); break; case ONE_PAIR: rank = find_extrema(LUMP_NORMALIZED & (~pairs), 3); break; case TWO_PAIR: rank = find_extrema(LUMP_NORMALIZED & (~pairs), 1); break; case THREE_OF_A_KIND: rank = find_extrema(LUMP_NORMALIZED & (~triplet), 2); break; case FLUSH: rank = find_extrema(rank, 5); break; case FOUR_OF_A_KIND: rank = find_extrema(LUMP_NORMALIZED & (~quadruplet), 1); break; } best_hand->category = type; best_hand->quadruplet = quadruplet; best_hand->triplet = triplet; best_hand->pairs = pairs; best_hand->rank = rank; }