public static long eval(CardSet cs) { final long enc = HandEvaluator.encode(cs); int val = 0; switch (cs.size()) { case 2: final int r0 = cs.get(0).getRank().ordinal(); final int r1 = cs.get(1).getRank().ordinal(); final int s0 = cs.get(0).getSuit().ordinal(); final int s1 = cs.get(1).getSuit().ordinal(); if (r0 == r1) { val = 1 << 9; } val |= Math.max(r0, r1) << 5; val |= Math.min(r0, r1) << 1; if (s0 == s1) { val |= 1; } break; case 5: val = HandEvaluator.hand5Eval(enc); break; case 6: val = HandEvaluator.hand6Eval(enc); break; case 7: val = HandEvaluator.hand7Eval(enc); break; } return val; }
// initializer block static { int mask, bitCount; int shiftReg, i; int value; for (mask = 1; mask < HandEvaluator.ARRAY_SIZE; ++mask) { bitCount = 0; shiftReg = mask; for (i = HandEvaluator.ACE_RANK - 1; i > 0; --i, shiftReg <<= 1) { if ((shiftReg & 0x1000) != 0) { switch (++bitCount) { case 1: HandEvaluator.hiTopRankTWO_PAIR[mask] = HandEvaluator.TWO_PAIR | ((i + 1) << HandEvaluator.TOP_SHIFT); HandEvaluator.hiBotRank[mask] = (i + 1) << HandEvaluator.BOT_SHIFT; HandEvaluator.hiRankMask[mask] = 0x1000 >> (HandEvaluator.ACE_RANK - 1 - i); break; case 2: HandEvaluator.hi2RanksMask[mask] = (shiftReg & 0x03FFF000) >> (HandEvaluator.ACE_RANK - 1 - i); break; case 3: HandEvaluator.hi3RanksMask[mask] = (shiftReg & 0x03FFF000) >> (HandEvaluator.ACE_RANK - 1 - i); break; case 5: HandEvaluator.hi5RanksMask[mask] = (shiftReg & 0x03FFF000) >> (HandEvaluator.ACE_RANK - 1 - i); } } } HandEvaluator.nbrOfRanks[mask] = bitCount; bitCount = 0; /* rotate the 13 bits left to get ace into LS bit */ /* we don't need to mask the low 13 bits of the result */ /* as we're going to look only at the low order 8 bits */ shiftReg = (mask << 1) + ((mask ^ 0x1000) >> 12); value = 0; for (i = 0; i < 8; ++i, shiftReg >>= 1) { if ((shiftReg & 1) != 0) { value |= (1 << i); /* undo previous shifts, copy bit */ if (++bitCount == 5) { HandEvaluator.lo5RanksMask[mask] = value; break; } if (bitCount == 3) { HandEvaluator.lo3RanksMask[mask] = value; } } } HandEvaluator.loEvalOrNo8Low[mask] = (bitCount == 5) ? value : HandEvaluator.NO_8_LOW; } for (mask = 0x1F00 /* A..T */; mask >= 0x001F /* 6..2 */; mask >>= 1) { HandEvaluator.setStraight(mask); } HandEvaluator.setStraight(HandEvaluator.WHEEL); /* A,5..2 */ }
/** * Returns a value which can be used as a parameter to one of the HandEval evaluation methods. * * @param cs a {@link CardSet} * @return a value which can be used as a parameter to one of the HandEval evaluation methods. The * value may also be bitwise OR'ed or added to other such values to build an evaluation method * parameter. */ public static long encode(final CardSet cs) { long result = 0; for (final Card c : cs) { result |= HandEvaluator.encode(c); } return result; }
/** * Returns the value of the best 5-card high poker hand from 7 cards. * * @param hand bit mask with one bit set for each of 7 cards. * @return the value of the best 5-card high poker hand. */ public static int hand7Eval(long hand) { int i, j, ranks; /* * The low-order 52 bits of hand contains four 13-bit fields, one * field per suit. The high-order 12 bits are clear. Get the * respective fields into variables. * We don't care which suit is which; we arbitrarily call them c,d,h,s. */ final int c = (int) hand & 0x1FFF; final int d = ((int) hand >>> 13) & 0x1FFF; final int h = (int) (hand >>> 26) & 0x1FFF; final int s = (int) (hand >>> 39); switch (HandEvaluator.nbrOfRanks[ranks = c | d | h | s]) { case 2: /* * quads with trips kicker */ i = c & d & h & s; /* bit for quads */ return HandEvaluator.FOUR_OF_A_KIND | HandEvaluator.hiBotRank[i] | (i ^ ranks); case 3: /* * trips and pair (full house) with non-playing pair, * or two trips (full house) with non-playing singleton, * or quads with pair and singleton */ /* bits for singleton, if any, and trips, if any: */ if (HandEvaluator.nbrOfRanks[i = c ^ d ^ h ^ s] == 3) { /* two trips (full house) with non-playing singleton */ if (HandEvaluator.nbrOfRanks[i = c & d] != 2) { if (HandEvaluator.nbrOfRanks[i = c & h] != 2) { if (HandEvaluator.nbrOfRanks[i = c & s] != 2) { if (HandEvaluator.nbrOfRanks[i = d & h] != 2) { if (HandEvaluator.nbrOfRanks[i = d & s] != 2) { i = h & s; /* bits for the trips */ } } } } } return HandEvaluator.FULL_HOUSE | HandEvaluator.hiBotRank[i] | (i ^ HandEvaluator.hiRankMask[i]); } if ((j = c & d & h & s) != 0) { /* quads with pair and singleton */ return HandEvaluator.FOUR_OF_A_KIND | HandEvaluator.hiBotRank[j] | (HandEvaluator.hiRankMask[ranks ^ j]); } /* trips and pair (full house) with non-playing pair */ return HandEvaluator.FULL_HOUSE | HandEvaluator.hiBotRank[i] | (HandEvaluator.hiRankMask[ranks ^ i]); case 4: /* * three pair and singleton, * or trips and pair (full house) and two non-playing singletons, * or quads with singleton kicker and two non-playing singletons */ i = c ^ d ^ h ^ s; // the bit(s) of the trips, if any, and singleton(s) if (HandEvaluator.nbrOfRanks[i] == 1) { /* three pair and singleton */ j = ranks ^ i; /* the three bits for the pairs */ ranks = HandEvaluator.hiRankMask[j]; /* bit for the top pair */ j ^= ranks; /* bits for the two bottom pairs */ return HandEvaluator.hiTopRankTWO_PAIR[ranks] | HandEvaluator.hiBotRank[j] | HandEvaluator.hiRankMask[(HandEvaluator.hiRankMask[j] ^ j) | i]; } if ((j = c & d & h & s) == 0) { // trips and pair (full house) and two non-playing singletons i ^= ranks; /* bit for the pair */ if ((j = (c & d) & (~i)) == 0) { j = (h & s) & (~i); /* bit for the trips */ } return HandEvaluator.FULL_HOUSE | HandEvaluator.hiBotRank[j] | i; } // quads with singleton kicker and two non-playing singletons return HandEvaluator.FOUR_OF_A_KIND | HandEvaluator.hiBotRank[j] | (HandEvaluator.hiRankMask[i]); case 5: /* * flush and/or straight, * or two pair and three singletons, * or trips and four singletons */ if ((i = HandEvaluator.flushAndOrStraight7(ranks, c, d, h, s)) != 0) { return i; } i = c ^ d ^ h ^ s; // the bits of the trips, if any, and singletons if (HandEvaluator.nbrOfRanks[i] != 5) { /* two pair and three singletons */ j = i ^ ranks; /* the two bits for the pairs */ return HandEvaluator.hiTopRankTWO_PAIR[j] | HandEvaluator.hiBotRank[HandEvaluator.hiRankMask[j] ^ j] | HandEvaluator.hiRankMask[i]; } /* trips and four singletons */ if ((j = c & d) == 0) { j = h & s; } return HandEvaluator.THREE_OF_A_KIND | HandEvaluator.hiBotRank[j] | (HandEvaluator.hi2RanksMask[i ^ j]); case 6: /* * flush and/or straight, * or one pair and three kickers and two nonplaying singletons */ if ((i = HandEvaluator.flushAndOrStraight7(ranks, c, d, h, s)) != 0) { return i; } i = c ^ d ^ h ^ s; /* the bits of the five singletons */ return HandEvaluator.PAIR | HandEvaluator.hiBotRank[ranks ^ i] | HandEvaluator.hi3RanksMask[i]; case 7: /* * flush and/or straight or no pair */ if ((i = HandEvaluator.flushAndOrStraight7(ranks, c, d, h, s)) != 0) { return i; } return /* NO_PAIR | */ HandEvaluator.hi5RanksMask[ranks]; } /* end switch */ return 0; /* never reached, but avoids compiler warning */ }
/** * Returns the value of the best 5-card high poker hand from 6 cards. * * @param hand bit mask with one bit set for each of 6 cards. * @return the value of the best 5-card high poker hand. */ public static int hand6Eval(long hand) { final int c = (int) hand & 0x1FFF; final int d = ((int) hand >>> 13) & 0x1FFF; final int h = (int) (hand >>> 26) & 0x1FFF; final int s = (int) (hand >>> 39); final int ranks = c | d | h | s; int i, j, k; switch (HandEvaluator.nbrOfRanks[ranks]) { case 2: /* * quads with pair kicker, * or two trips (full house) */ /* bits for trips, if any: */ if ((HandEvaluator.nbrOfRanks[i = c ^ d ^ h ^ s]) != 0) { /* two trips (full house) */ return HandEvaluator.FULL_HOUSE | HandEvaluator.hiBotRank[i] | (i ^ HandEvaluator.hiRankMask[i]); } /* quads with pair kicker */ i = c & d & h & s; /* bit for quads */ return HandEvaluator.FOUR_OF_A_KIND | HandEvaluator.hiBotRank[i] | (i ^ ranks); case 3: /* * quads with singleton kicker and non-playing singleton, * or full house with non-playing singleton, * or two pair with non-playing pair */ if ((c ^ d ^ h ^ s) == 0) { /* no trips or singletons: three pair */ i = HandEvaluator.hiRankMask[ranks]; /* bit for the top pair */ k = ranks ^ i; /* bits for the bottom two pairs */ j = HandEvaluator.hiRankMask[k]; /* bit for the middle pair */ return HandEvaluator.hiTopRankTWO_PAIR[i] | HandEvaluator.hiBotRank[j] | (k ^ j); } if ((i = c & d & h & s) == 0) { /* full house with singleton */ if ((i = c & d & h) == 0) { if ((i = c & d & s) == 0) { if ((i = c & h & s) == 0) { i = d & h & s; /* bit of trips */ } } } j = c ^ d ^ h ^ s; /* * the bits of the trips * and singleton */ return HandEvaluator.FULL_HOUSE | HandEvaluator.hiBotRank[i] | (j ^ ranks); } /* quads with kicker and singleton */ return HandEvaluator.FOUR_OF_A_KIND | HandEvaluator.hiBotRank[i] | (HandEvaluator.hiRankMask[i ^ ranks]); case 4: /* * trips and three singletons, * or two pair and two singletons */ if ((i = c ^ d ^ h ^ s) != ranks) { /* two pair and two singletons */ j = i ^ ranks; /* the two bits for the pairs */ return HandEvaluator.hiTopRankTWO_PAIR[j] | HandEvaluator.hiBotRank[HandEvaluator.hiRankMask[j] ^ j] | HandEvaluator.hiRankMask[i]; } /* trips and three singletons */ if ((i = c & d) == 0) { i = h & s; /* bit of trips */ } return HandEvaluator.THREE_OF_A_KIND | HandEvaluator.hiBotRank[i] | (HandEvaluator.hi2RanksMask[i ^ ranks]); case 5: /* * flush and/or straight, * or one pair and three kickers and * one non-playing singleton */ if ((i = HandEvaluator.flushAndOrStraight6(ranks, c, d, h, s)) != 0) { return i; } i = c ^ d ^ h ^ s; /* the bits of the four singletons */ return HandEvaluator.PAIR | HandEvaluator.hiBotRank[ranks ^ i] | HandEvaluator.hi3RanksMask[i]; case 6: /* flush and/or straight or no pair */ if ((i = HandEvaluator.flushAndOrStraight6(ranks, c, d, h, s)) != 0) { return i; } return /* NO_PAIR | */ HandEvaluator.hi5RanksMask[ranks]; } /* end switch */ return 0; /* never reached, but avoids compiler warning */ }