Described in this email is the stats project I described to Loic in Las
Vegas.  I was thinking about it again today and don't have time to work
on it, but I wanted to write up a project description in case someone
else wants to give it a try.

Since this project seems somewhat an extension to the work proppy was
doing at on odds.aminche.com, I put this up as
http://odds.aminche.com/#NextGenerationIdea as well.



                          PROJECT DESCRIPTION
                NEXT GENERATION IN POKER STATS SOFTWARE
                            Bradley M. Kuhn


                        BACKGROUND AND RATIONALE

The poker-eval library, which was floating around since the early 1990s,
has been often used by new players to begin to understand the
statistical situations that occur in hand lineups.  Indeed, in a
geek-home-game that I once frequented in Boston, it was very popular,
upon an all-in situation on the flop, for someone to pull out a laptop
and run hcmp2/pokenum to *prove* he was right that he got his money in
as a favorite.

Certainly, using hcmp2 or pokenum has helped many new players understand
why certain hands that are likely not "best" are still strong holdings
and want to be played aggressively even against a likely "better" hand
when there are cards to come.  For example, pokenum taught many of us
that semi-bluffing all-in (when stacks are medium-deep) with middle pair
and a flush draw against a likely weak top pair is an excellent play:

$ pokenum  -h ac qc  - 7d 5d  -- 7c 3d qd 
Holdem Hi: 990 enumerated boards containing 7c Qd 3d
cards  win   %win  lose  %lose  tie  %tie     EV
Ac Qc  494  49.90   496  50.10    0  0.00  0.499
7d 5d  496  50.10   494  49.90    0  0.00  0.501

We quickly see that the Hero (holding 5d7d) is a slight favorite, thus
when factoring in even a little bit of fold equity, it's clear that the
Hero should put the money in even if Hero "knows" the Villain has TPTK.

Indeed, I even wrote a rudimentary Perl script at one point to wrap
pokenum and calculate the win/loss percentage and EV based on the idea
that the Villain has a set N% of the time, top pair N%, etc.

These sort of calculations are very helpful to the new player, and
everyone goes through a period in their poker education when do a lot of
these to get a feel for such situations.

However, I rarely do these sorts of things anymore, because I basically
know the math well and can get a rough estimate by sight when presented
with a situation and make the correct playing decision.  I think this is
common for most players.

Indeed, non-FLOSS geeks often used "twodimes.net", which is a simplistic
web interface to pokenum, and is similar to the work proppy did on
http://odds.aminche.com/.  However, once people get reasonably good at
poker, these types of calculations become less and less interesting, as
they have for me.

There are, however, calculations of interest to even the experienced
player, but they are tougher to describe.  I believe that such software
could be very helpful to players in an ongoing way, and it would be
particularly useful if an inventive AJAX interface (as well as a CLI, of
course) were designed to allow such calculations.

                             PROBLEM SPECIFICATION

The calculations that are complicated enough that experienced players
would seek to do would, most typically, involve a multi-street situation
against a somewhat knowledgeable opponent who will act differently based
on various complications.  This is best explained by stating a common
statistic question that a somewhat experienced player might ask:

  In NL HE, I often raise with AK in early position and receive one
  caller who has position.  Assuming that I and my opponent have stacks
  of 100 BBs, it would be useful to figure out what my EV is in
  continuation betting the flop when I flop only Ace-high.

  Let's assume that on the flop, when I bet 3/4ths the pot, my opponent
  acts as follows:

          (a) my opponent will call 60% of the time on the flop with
              middle pair with a non-overcard kicker, 

          (b) that he will call 65% of the time with middle pair and
              overcard, and raise 10% of the time in that situation.

          (c) slow play a set, a flopped straight, or a flopped flush,
              or any better hand, by just calling with a plan to raise
              the turn.

          (d) always raise with any top pair on a board that has a
              straight draw and a flush draw, and raise 80% of the time
              with top pair in other situations, and call the rest of
              the time.

  For simplicity, we assume that I am done with the hand (check-fold) if
  I still have only ace high on the turn, and I will bet half the pot on
  the turn and river when I turn an Ace or King, and always fold when
  raised, and assume my opponent will raise if he makes a set or better
  on the turn or river.


This is a relatively basic simulation, from a poker player's point of
view.  In other words, this is in the BOTTOM of complexity for the kinds
of statistic questions poker players want to ask.  It's easy to see how
we could increase or make more complex the situation, by adding
additional callers preflop, or by making our opponent more
sophisticated, or by adding in more options for what happens on the turn
or the river.

              THOUGHTS ON SOFTWARE API FOR DEFINING ACTION

The most difficult part of creating software for this purpose is the
interface for defining the situation.  A first step, therefore, would be
to create a series of objects (presumably in Python, so it could use the
rest of poker-engine and poker-network) that make it extremely easy to
program these types of actions by players in a hand together.  The API
needs the following things:

    (a) A SimulationActor class, that allows to create an object that
        has actions based on what betting round it is.

    (b) Board/Hand evaluation macros, that allow you to quantify a
        situation like "I want this player call 65% of the time with
        middle pair and overcard, and raise 10% of the time in that
        situation."  or "call 75% of a time with a straight draw without
        a flush draw possible, and raise 25% of the time".  

    (c) Hand range operators for evaluating starting hands. 


So, we might set up a situation this way (forgive the pseudo-code-ness):

            def villainFlopPlan(hand, flop):

                if flop.haveTopPair(hand) and flop.haveOvercard(hand)
                      and flop.haveNoStraightFlushDraw(flop):
                   return { call : 65%, raise : { 'half-pot', 10% },
                           fold : rest}
 
                # flushDraw(flop) might return things like
                # "backdoor-s;oneCard-h"

                elsif (not flop.flushDraw().find('oneCard')) and
                      flop.haveOpenEndedStraightDraw(hand):
                      return { call : 75%, raise { 'pot' : 25% } }

                return { fold : 100% }

            def villainHandSelection(startingHand):
                 if startingHand.suitedConnector(min = '45', max = 'AK'):
                    return { call : 100% }
                 elsif startingHand.tenPointers(hand = startingHand, min = 
'QT'):
                    return { call : 90% }
                 elsif startingHand.pairs(min = '55', max = 'TT'):
                    return { call : 100% }
                 # We don't care about hands he folds or reraises with
                 #  for this simulation
                 return { fold : 100% }

            def heroHandSelection(startingHand):
                 if startingHand.anySuits('AK'):
                    return { raise: {'pot' : 100% }}
                 return { fold : 100% }

            def heroFlopPlan(hand, flop):
                 return { bet: '3/4-pot' }

            sim = new Simulation('nl-he-100-200')
            villain = new SimulationActor(stack = 1000)
            villain.actionPlan('preflop', villainHandSelection)
            villain.actionPlan('flop', villainFlopPlan)

            hero = new SimulationActor(stack = 1000)
            hero.actionPlan('preflop', heroHandSelection)
            hero.actionPlan(flop, heroFlopPlan)
            
            sim.run({ actors : [ hero, villain ])
            # Returns EV for each player


                          NEXT STEPS AFTER API

The work above is not terribly difficult, although there is a lot of
grunt work involved.  The hard part after that is making that kind of
system accessible to non-programmers.  This is the area where my
expertise falls down; I can't imagine what a GUI would look like to make
programming those objects easy to a non-programmer.

But, that's where this becomes really interesting for some good UI
designer out there.  I imagine that a site that featured this sort of
system, if the interface were strong, would be quite popular and could
even support itself with advertising.

Some ideas I had is a sort of domain-specific language for defining
actions, which maybe would make it too much like programming.  Another
idea is some sort of line-based action rules like:

   HAND:  { (ACTION, PERCENT), (ACTION, PERCENT) ... }

  which would give an easy interface to a subset of what the API can
  actually do.


                           OTHER APPLICATIONS

Obviously, some the API I've suggested would be useful in implementing
bot players too.  I know some pokersource hackers are working on bot API
infrastructure, and I would encourage them to think about how this kind
of API could be used both for bots and simulation programming.  I think
the domains overlap enough that we should be general enough to support
both.


This document is Copyright (C) 2008, Bradley M. Kuhn.  I license it
under the disjunction of three licenses: GPLv3-or-later and
FDLv1.1-or-later and CC-By-SA-2.0-only.  Email me if you are confused
about licensing details.

-- 

   -- bkuhn

_______________________________________________
Pokersource-users mailing list
[email protected]
https://mail.gna.org/listinfo/pokersource-users

Reply via email to