TEST(OmahaHighHandEvaluator, RankEval) {
  OmahaHighHandEvaluator oeval;
  CardSet hand("2c3c");
  CardSet board("2c3c4c");
  PokerEvaluation eval = oeval.evaluateRanks(hand, board);
  EXPECT_EQ(TWO_PAIR, eval.type());
  EXPECT_EQ(Rank("3"), eval.majorRank());
  EXPECT_EQ(Rank("2"), eval.minorRank());
}
Exemplo n.º 2
0
// This one is not fully optimized
PokerEvaluation CardSet::evaluateRanksLow2to7() const
{
    PokerEvaluation high;
    PokerEvaluation h;

    // if there are five or fewer cards, we just evaluate the high,
    // fix the wheel, and take the complement
    switch (size())
    {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
        high = evaluateHighRanks();
        break;

    case 5:
        high = evaluateHighRanks();
        high.fixWheel2to7(rankMask());
        break;

    default:
        // this is a slow way to handle the general case.
        // TODO: specialize the code for the 6 and 7 card cases.
        vector<Card> cards = this->cards();
        combinations combo(size(), FULL_HAND_SIZE);
        PokerEvaluation best;
        do
        {
            CardSet candidate;
            for (size_t i=0; i<static_cast<size_t>(FULL_HAND_SIZE); i++)
                candidate.insert(cards[combo[i]]);
            PokerEvaluation e = candidate.evaluateRanksLow2to7();
            if (e > best)
                best = e;
        }
        while (combo.next());
        return best;

    }

    high.flip();
    return high;
}
Exemplo n.º 3
0
// This one is not fully optimized
PokerEvaluation CardSet::evaluateLowA5() const
{
    //PokerEvaluation::generateLowballLookupA5();

    // this is a rank only evaluator, so we just get
    // the rank masks and then fill accordingly.  We
    // also have to shift the rank mask according to the
    // the fact that the ace swings low
    // this could probably be much faster

    int c = C();
    int d = D();
    int h = H();
    int s = S();
    int rankmask = c | d | h | s;

    int ncards = nRanksTable[c] + nRanksTable[d] + nRanksTable[h] + nRanksTable[s];
    int ndups = ncards - nRanksTable[rankmask];
    int nranks = nRanksTable[rankmask];

    // first the easy cases
    // 1) no duplicate ranks
    // 2) 5 or more ranks
    if (ndups == 0 || nranks >= FULL_HAND_SIZE)
    {
        PokerEvaluation ret((NO_PAIR<<VSHIFT) ^ lowballA5Ranks[rankmask] ^ ACE_LOW_BIT);
        ret.flip();
        return ret;
    }
    // another easy case
    // *) we have five or fewer cards
    else if (ncards <= FULL_HAND_SIZE)
    {
        PokerEvaluation ret = evaluatePairing();
        ret.playAceLow();
        ret.flip();
        return ret;
    }
    else
    {
        // now the general case
        // the algorithm is as follows:
        // cycle through the "pairing list" till a total of five
        // cards are found
        uint64_t chash = 0;// = rankmask;
        int rset[4];

        rset[0]  = rankmask;
        rset[1]  = rankmask ^(c ^ d ^ h ^ s);             // mask of cards with 2/4 ranks
        rset[2]  = ((c&d)|(h&s)) & ((c&h)|(d&s));         // mask of cards with 3 ranks
        rset[3]  =  c & d & h & s;                        // fourmask
        rset[1] |= rset[2];       // add the threes back to teh twos

        rset[0] = LOWBALL_ROTATE_RANKS(rset[0]);
        rset[1] = LOWBALL_ROTATE_RANKS(rset[1]);
        rset[2] = LOWBALL_ROTATE_RANKS(rset[2]);
        rset[3] = LOWBALL_ROTATE_RANKS(rset[3]);

        // we add pairs first, then trips, then quads
        int nc=0;
        for (int i=0; i<4; i++)
        {
            // do the ace first
            if (rset[i] & (0x01<<Rank::AceVal()))
            {
                chash |= (ONE64<<(Rank::AceVal()+Rank::NUM_RANK*i));
                nc++;
            }
            if (nc == FULL_HAND_SIZE)
            {
                break;
            }

            // now the rest of the ranks
            for (int r=0; r<11; r++)
            {
                if (rset[i] & (0x01<<r))
                {
                    chash |= (ONE64<<(r+Rank::NUM_RANK*i));
                    nc++;
                }
                if (nc == FULL_HAND_SIZE)
                {
                    break;
                }
            }
            if (nc == FULL_HAND_SIZE)
            {
                break;
            }
        }

        CardSet paird(chash);
        PokerEvaluation ret(paird.evaluatePairing().code() | ACE_LOW_BIT);
        ret.flip();
        return ret;
    }
}
Exemplo n.º 4
0
void PokerHand::sortEval () const
{
  PokerHand oldh = *this;
  PokerHand newh;
  PokerEvaluation eval = cardSet().evaluateHigh ();
  Rank r;
  bool dominor = true;
  Rank straighttop = Rank::Five();

  oldh.sortRanks ();
  switch (eval.type ())
    {
      // these types have major only
    case ONE_PAIR:
    case THREE_OF_A_KIND:
    case FOUR_OF_A_KIND:
      dominor = false;

      // these have major and minor
    case TWO_PAIR:
    case FULL_HOUSE:
      r = eval.majorRank ();
      while (oldh.cardSet().contains (r))
        {
          Card c = oldh.cardSet().find (r);
          newh.append (c);
          oldh.remove (c);
        }
      if (dominor)
        {
          r = eval.minorRank ();
          while (oldh.cardSet().contains (r))
            {
              Card c = oldh.cardSet().find (r);
              newh.append (c);
              oldh.remove (c);
            }
        }
      // we pass through here, no break

    case NO_PAIR:
    case THREE_FLUSH:
    case THREE_STRAIGHT_FLUSH:
    case FLUSH:
      newh.append (oldh);
      break;

      // straights may require the ace to swing low
    case THREE_STRAIGHT:
      straighttop = Rank::Three();
    case STRAIGHT:
    case STRAIGHT_FLUSH:
      newh = oldh;
      r = eval.majorRank ();
      if (r == straighttop)
        {
          Card c = newh.cardSet().find (Rank::Ace());
          newh.remove (c);
          newh.append (c);
        }
      break;


    }

  for (int i=0; i<_ncards; i++)
    _cards[i] = newh._cards[i];
}