Tuesday, June 06, 2006
I'm sure you've read a book or two on Holdem. One of the things I noticed while reading poker books is that there is a de facto standard for describing pocket cards. Most books use some variant of the following to describe pocket hands.
Most poker software that parse string representations of pocket hands only supports the first item in the de facto standard.
I've implemented a much richer query language. I support all of the common poker book syntax plus some extensions.
I've also added some operators.
Why a Pocket Query Language?
One of the things I've done too many times has been write code to analyze specific matchups. For example, have you ever wondered what the advantage is for have a suited connected verses a non-suited connector?
I'd guess you've probably wondered, but weren't enough of a masochist to write the code. On the other hand, I am enough of a masochist to write the code for many, many match ups. After awhile I decide I had enough of that and wrote a query language so that I could write my matchup analysis once and just put in query strings.
The following is an example of the result of using query strings rather than hard coded match ups. Oh and there is about a 5% advantage for suited connectors.
I've attempted to make it trivial to write analysis code that utilized Pocket Queries. Here's an example.
static void Main(string args)
// A Pocket Query Returns an array of all
// hands that meet the criterion.
ulong player1 = PocketHands.Query("Group3-Group5");
ulong player2 = PocketHands.Query("Axs");
// Holds stats
long player1Wins = 0, player2Wins = 0,
ties = 0, count = 0;
// Iterate through 10000 trials.
for (int trials = 0; trials < 10000; trials++)
// Pick a random pocket hand out of player1's query set
ulong player1Mask = Hand.RandomHand(player1, 0UL, 2);
// Pick a random pocket hand for player2
ulong player2Mask = Hand.RandomHand(player2, player1Mask, 2);
// Pick a random board
ulong boardMask = Hand.RandomHand(player1Mask |player2Mask, 5);
// Create a hand value for each player
uint player1HandValue = Hand.Evaluate(boardMask | player1Mask, 7);
uint player2HandValue = Hand.Evaluate(boardMask | player2Mask, 7);
// Calculate Winners
if (player1HandValue > player2HandValue)
else if (player1HandValue < player2HandValue)
// Print results
(player1Wins + ties/2.0) / ((double)count) * 100.0);
(player2Wins + ties/2.0) / ((double)count) * 100.0);