// Ex. 7 // Evaluates hand int evaluate_hand(card* hand) { sort_hand(hand); int straight_flag = is_straight(hand); if(is_same_suit(hand)) { if((hand[0].value == 8) && (straight_flag)) return 9; // If the 1st card is Ten and the cards form a straight, return 9 (Royal flush) if(straight_flag) return 8; // If the cards form a straight, return 8 (Straight flush) else return 5; // Otherwise, return 5 (Flush) } else if(is_four_of_a_kind(hand)) return 7; else if(is_full_house(hand)) return 6; else if(straight_flag) return 4; else if(is_three_of_a_kind(hand)) return 3; else if(is_two_pairs(hand)) return 2; else if(has_pair(hand)) return 1; return 0; // If none of these evaluations holds, return 0 (Bust) }
void Evaluator::determine_strength(HandStrength *strength) { // sort cards descending std::sort(all_cards.begin(), all_cards.end(), Card::greater); // clear combination cards and kicker_cards strength->clear_combination_cards(); strength->clear_kicker_cards(); // test for all combinations bool isFlush; if ((isFlush = is_flush(strength)) && is_straight(strength, strength->get_combination_cards()->front()->get_suit())) { strength->set_combination(HandStrength::STRAIGHT_FLUSH); // check royal flush if (strength->get_combination_cards()->front()->get_face() == Card::ACE) { strength->set_combination(HandStrength::ROYAL_FLUSH); } } else if (is_X_of_a_kind(FOUR_OF_A_KIND_SIZE, strength)) { strength->set_combination(HandStrength::FOUR_OF_A_KIND); } else if (is_full_house(strength)) { strength->set_combination(HandStrength::FULL_HOUSE); } else if (isFlush) { strength->set_combination(HandStrength::FLUSH); } else if (is_straight(strength)) { strength->set_combination(HandStrength:: STRAIGHT); } else if (is_X_of_a_kind(THREE_OF_A_KIND_SIZE, strength)) { strength->set_combination(HandStrength::TREE_OF_A_KIND); } else if (is_two_pairs(strength)) { strength->set_combination(HandStrength::TWO_PAIRS); } else if (is_X_of_a_kind(PAIR_SIZE, strength)) { strength->set_combination(HandStrength::PAIR); } else { strength->set_combination(HandStrength::HIGH_CARD); strength->clear_combination_cards(); strength->add_to_combination_cards(all_cards.front()); strength->clear_kicker_cards(); for (card_it card = all_cards.begin() + 1; card != all_cards.end() && strength->get_kicker_cards()->size() < HandStrength::KICKER_CARDS_SIZE - 1; ++card) { strength->add_to_kicker_cards(*card); } } }
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; }