c++poker

Programming a Poker Hand Calculator in C++


I've written a few hundred lines of code for a 5 card Poker Hand Calculator in C++ to practice using classes. Here is part of the member function I've written to compare two hands that are both TwoPairs. I've thoroughly tested all of my boolean functions and they all work except the ones to compare TwoPairs, OnePairs, and HighCard hands.

// If both hands are TwoPairs, the highest value pairs are compared.
else if (m_rank == TwoPair) {
  if (m_firstPairPoints > otherHand.m_firstPairPoints) {
    return 1;
  }
  else if (m_firstPairPoints < otherHand.m_firstPairPoints) {
    return -1;
  }
  // If the highest pairs are equal, the next lowest pairs are
  // compared.
  else if (m_firstPairPoints == otherHand.m_firstPairPoints) {
    if (m_secondPairPoints > otherHand.m_firstPairPoints) {
      return 1;
    }
    else if (m_secondPairPoints < otherHand.m_secondPairPoints) {
      return -1;
    }
    // If both pairs are equal, the kickers are compared.
    else if (m_secondPairPoints == otherHand.m_secondPairPoints) {
      if (m_lastCardPoints > otherHand.m_lastCardPoints) {
        return 1;
      } 
      else if (m_lastCardPoints < otherHand.m_lastCardPoints) {
        return -1;
      }
      else {
        return 0;
      }
    }
  }  
}

Here is the Boolean function itself that sets the values for the member variables used in the comparison function fragment I entered above:

// Implementation of the isTwoPair bool function.
bool PokerHand::isTwoPair(){
  bool checkVar = true;

  // If the single card is the first element.
  if (m_cards[0].points() != m_cards[1].points() &&
      m_cards[0].points() != m_cards[3].points() &&
      m_cards[1].points() == m_cards[2].points() &&
      m_cards[3].points() == m_cards[4].points()) {
    m_rank = TwoPair;
    m_firstPairPoints = m_cards[3].points();
    m_secondPairPoints = m_cards[1].points();
    m_lastCardPoints = m_cards[0].points();
  }

  // If the single card is in the middle.
  else if (m_cards[0].points() == m_cards[1].points() &&
      m_cards[2].points() != m_cards[0].points() &&
      m_cards[2].points() != m_cards[3].points() &&
      m_cards[3].points() == m_cards[4].points()) {
    m_rank = TwoPair;
    m_firstPairPoints = m_cards[3].points();
    m_secondPairPoints = m_cards[0].points();
    m_lastCardPoints = m_cards[2].points();
  }

  //If the single card is the last element.
  else if (m_cards[0].points() == m_cards[1].points() &&
      m_cards[2].points() == m_cards[3].points() &&
      m_cards[4].points() != m_cards[0].points() &&
      m_cards[4].points() != m_cards[2].points()) {
    m_rank = TwoPair;
    m_firstPairPoints = m_cards[2].points();
    m_secondPairPoints = m_cards[0].points();
    m_lastCardPoints = m_cards[4].points();
  }
  else {
    checkVar = false;
  }
  return checkVar;
}

So right now my issue is that for the TwoPair, OnePair, and HighCard hands, no matter what I do, my test cpp file always outputs that the same hand wins (always returns 1) when they are of one of these 3 ranks. Even if I blatantly stack the deck so to speak. Been trying different stuff for hours now and I'm not quite sure what's going on. I've even tried rewriting the 3 fragments of the comparison function for these three ranks several times from scratch. Any tips you folks would have are more than welcome. Also, please keep in mind that I'm a neophyte still if it wasn't obvious, and have limitations on what built-in functions I'm allowed to use for this project.


Solution

  • You're making it far too hard for yourself. You're missing an intermediate step: count how many cards you have of each rank, ignoring suit. So you get a std::array<int, 13> ranktotal (or int [13] if your teacher/book is outdated).

    Now once you have that, a "2 pair" hand is a 2-2-1 pattern of ranks, and you can easily find the first 2. Similarly, a full house is a 2-3. A straight is a series of 5 ones without a 0 in between.