Example #1
0
vector<Equity> Evaluator::evalHoldemHands(const vector<CardSet>& hands,
                                          const CardSet& board,
                                          const CardSet& dead) {
  size_t numPlayers = hands.size();
  vector<Equity> equities(numPlayers);

  vector<bool> isUsed(Card::MAX_ID + 1);
  bool IsValidGame = board.IsValid() && dead.IsValid();

  for (auto hand : hands) {
    IsValidGame &= hand.IsValid(2);
    for (auto card : hand.ToCards()) {
      IsValidGame &= !isUsed[card.id()];
      isUsed[card.id()] = true;
    }
  }

  for (auto card : board.ToCards()) {
    IsValidGame &= !isUsed[card.id()];
    isUsed[card.id()] = true;
  }

  for (auto card : dead.ToCards()) {
    IsValidGame &= !isUsed[card.id()];
    isUsed[card.id()] = true;
  }

  if (!IsValidGame) {
    return equities;
  }

  vector<int> ranks(numPlayers);

  vector<int> starts(5, 1);
  vector<int> ends(5, Card::MAX_ID);

  for (size_t i = 0; i < board.ToCards().size(); ++i) {
    starts[i] = ends[i] = board.ToCards()[i].id();
  }

  for (int h0 = starts[0]; h0 <= ends[0]; ++h0) {
    if (board.ToCards().empty() && isUsed[h0]) {
      continue;
    }

    if (board.ToCards().empty()) {
      isUsed[h0] = true;
      starts[1] = h0 + 1;
    }

    int r0 = handRanks[h0 + Card::MAX_ID + 1];

    for (int h1 = starts[1]; h1 <= ends[1]; ++h1) {
      if (board.ToCards().size() <= 1 && isUsed[h1]) {
        continue;
      }

      if (board.ToCards().size() <= 1) {
        isUsed[h1] = true;
        starts[2] = h1 + 1;
      }

      int r1 = handRanks[h1 + r0];
      for (int h2 = starts[2]; h2 <= ends[2]; ++h2) {
        if (board.ToCards().size() <= 2 && isUsed[h2]) {
          continue;
        }

        if (board.ToCards().size() <= 2) {
          isUsed[h2] = true;
          starts[3] = h2 + 1;
        }

        int r2 = handRanks[h2 + r1];
        for (int h3 = starts[3]; h3 <= ends[3]; ++h3) {
          if (board.ToCards().size() <= 3 && isUsed[h3]) {
            continue;
          }

          if (board.ToCards().size() <= 3) {
            isUsed[h3] = true;
            starts[4] = h3 + 1;
          }

          int r3 = handRanks[h3 + r2];
          for (int h4 = starts[4]; h4 <= ends[4]; ++h4) {
            if (board.ToCards().size() <= 4 && isUsed[h4]) {
              continue;
            }

            int r4 = handRanks[h4 + r3];
            int maxRank = -1;
            int numBestPlayers = 0;

            for (size_t i = 0; i < numPlayers; ++i) {
              ranks[i] = r4;
              for (auto card : hands[i].ToCards()) {
                ranks[i] = handRanks[ranks[i] + card.id()];
              }

              if (maxRank == ranks[i]) {
                ++numBestPlayers;
              } else if (maxRank < ranks[i]) {
                maxRank = ranks[i];
                numBestPlayers = 1;
              }
            }

            for (size_t i = 0; i < numPlayers; ++i) {
              if (ranks[i] == maxRank) {
                equities[i].addTie(numBestPlayers);
              } else {
                equities[i].addLose();
              }
            }
          }

          if (board.ToCards().size() <= 3) {
            isUsed[h3] = false;
          }
        }

        if (board.ToCards().size() <= 2) {
          isUsed[h2] = false;
        }
      }

      if (board.ToCards().size() <= 1) {
        isUsed[h1] = false;
      }
    }

    if (board.ToCards().empty()) {
      isUsed[h0] = false;
    }
  }

  return equities;
}
Example #2
0
vector<Equity> Evaluator::evalOmahaHands(const vector<CardSet>& hands,
                                         const CardSet& board,
                                         const CardSet& dead) {
  size_t numPlayers = hands.size();
  vector<Equity> equities(numPlayers);

  vector<bool> isUsed(Card::MAX_ID + 1);
  bool IsValidGame = board.IsValid() && dead.IsValid();

  for (auto hand : hands) {
    IsValidGame &= hand.IsValid(2);
    for (auto card : hand.ToCards()) {
      IsValidGame &= !isUsed[card.id()];
      isUsed[card.id()] = true;
    }
  }

  for (auto card : board.ToCards()) {
    IsValidGame &= !isUsed[card.id()];
    isUsed[card.id()] = true;
  }

  for (auto card : dead.ToCards()) {
    IsValidGame &= !isUsed[card.id()];
    isUsed[card.id()] = true;
  }

  if (!IsValidGame) {
    return equities;
  }

  vector<int> ranks(numPlayers);

  vector<int> starts(5, 1);
  vector<int> ends(5, Card::MAX_ID);

  for (size_t i = 0; i < board.ToCards().size(); ++i) {
    starts[i] = ends[i] = board.ToCards()[i].id();
  }

  for (int h0 = starts[0]; h0 <= ends[0]; ++h0) {
    if (board.ToCards().size() <= 0 && isUsed[h0]) {
      continue;
    }

    if (board.ToCards().size() <= 0) {
      isUsed[h0] = true;
      starts[1] = h0 + 1;
    }

    for (int h1 = starts[1]; h1 <= ends[1]; ++h1) {
      if (board.ToCards().size() <= 1 && isUsed[h1]) {
        continue;
      }

      if (board.ToCards().size() <= 1) {
        isUsed[h1] = true;
        starts[2] = h1 + 1;
      }

      for (int h2 = starts[2]; h2 <= ends[2]; ++h2) {
        if (board.ToCards().size() <= 2 && isUsed[h2]) {
          continue;
        }

        if (board.ToCards().size() <= 2) {
          isUsed[h2] = true;
          starts[3] = h2 + 1;
        }

        for (int h3 = starts[3]; h3 <= ends[3]; ++h3) {
          if (board.ToCards().size() <= 3 && isUsed[h3]) {
            continue;
          }

          if (board.ToCards().size() <= 3) {
            isUsed[h3] = true;
            starts[4] = h3 + 1;
          }

          for (int h4 = starts[4]; h4 <= ends[4]; ++h4) {
            if (board.ToCards().size() <= 4 && isUsed[h4]) {
              continue;
            }

            int maxRank = -1;
            int numBestPlayers = 0;

            array<int, 5> currentBoard = {{h0, h1, h2, h3, h4}};

            for (size_t i = 0; i < numPlayers; ++i) {
              size_t numCards = hands[i].ToCards().size();

              for (size_t b0 = 0; b0 < 5; ++b0) {
                for (size_t b1 = b0 + 1; b1 < 5; ++b1) {
                  for (size_t b2 = b1 + 1; b2 < 5; ++b2) {
                    for (size_t p0 = 0; p0 < numCards; ++p0) {
                      for (size_t p1 = p0 + 1; p1 < numCards; ++p1) {
                        array<int, 5> currentHand = {
                            {currentBoard[b0], currentBoard[b1],
                             currentBoard[b2],
                             static_cast<int>(hands[i].ToCards()[p0].id()),
                             static_cast<int>(hands[i].ToCards()[p1].id())}};

                        int currentRank = Card::MAX_ID + 1;
                        for (size_t hand : currentHand) {
                          currentRank = handRanks[currentRank + hand];
                        }

                        currentRank = handRanks[currentRank];
                        ranks[i] = max(ranks[i], currentRank);
                      }
                    }
                  }
                }
              }

              if (maxRank == ranks[i]) {
                ++numBestPlayers;
              } else if (maxRank < ranks[i]) {
                maxRank = ranks[i];
                numBestPlayers = 1;
              }
            }

            for (size_t i = 0; i < numPlayers; ++i) {
              if (ranks[i] == maxRank) {
                equities[i].addTie(numBestPlayers);
              } else {
                equities[i].addLose();
              }
            }
          }

          if (board.ToCards().size() <= 3) {
            isUsed[h3] = false;
          }
        }

        if (board.ToCards().size() <= 2) {
          isUsed[h2] = false;
        }
      }

      if (board.ToCards().size() <= 1) {
        isUsed[h1] = false;
      }
    }

    if (board.ToCards().size() <= 0) {
      isUsed[h0] = false;
    }
  }

  return equities;
}