I've recently started using the pokerstove library (https://github.com/andrewprock/pokerstove) and managed to perform some basic hand / equity evaluations with it. Unfortunately, as soon as I tried to write a bit more computationally expensive programs, I ran into massive performance issues that couldn't figure out how to deal with.
As an example I've provided the following program that calculates the average equity that the hand Ace-6 of spades has against a completely random hand:
#include <iostream>
#include <vector>
#include <pokerstove/penum/ShowdownEnumerator.h>
int main() {
using namespace pokerstove;
using namespace std;
CardSet completeDeck;
completeDeck.fill();
cout << "The whole deck has " << completeDeck.size() << " cards" << endl;
CardDistribution anyTwo;
anyTwo.fill(completeDeck, 2);
cout << "There are " << anyTwo.size() << " two card combinations" << endl;
CardDistribution holeCards;
holeCards.parse("As6s");
ShowdownEnumerator showdown;
vector<EquityResult> result = showdown.calculateEquity(
vector<CardDistribution>{anyTwo, holeCards},
CardSet(""),
PokerHandEvaluator::alloc("h")
);
double shareRandom = result.at(0).winShares + result.at(0).tieShares;
double shareHand = result.at(1).winShares + result.at(1).tieShares;
double total = shareRandom + shareHand;
cout << "A random hand has " << shareRandom / total * 100 << " % equity (" << result.at(0).str() << ")" << endl;
cout << "The hand As6s has " << shareHand / total * 100 << " % equity (" << result.at(1).str() << ")" << endl;
}
Once it finally stops, it outputs
The whole deck has 52 cards
There are 1326 two card combinations
A random hand has 40.0942 % equity (804780676 36223609 0 0)
The hand As6s has 59.9058 % equity (1220344506 36223609 0 0)
On my machine (which I admit isn't particularly fast) this computation takes roughly 4 minutes! Since this seems unreasonably long I belief that there has to be something wrong (performance-wise) with this implementation.
Hence, I would be very grateful if anybody could point out to me where I'm doing something wrong / inefficient.
I would suspect that one can reduce the number of random hands from 1326 to 169 (due to equivalence of suits), but I didn't find a way to implement that behaviour.
Any help is appreciated!
The short answer is: that's how fast it goes.
A longer answer is, this version is a general purpose evaluator capable of evaluating any kind of game. It does not do anything fancy like caching results, precomputing large tables, using suit isomorphisms, or anything else.