Poker-AI.org

Poker AI and Botting Discussion Forum
It is currently Mon Nov 13, 2023 2:24 pm

All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: Error in EHS calculation
PostPosted: Sun Aug 25, 2013 4:17 pm 
Offline
New Member

Joined: Thu May 30, 2013 11:49 am
Posts: 2
Hi, I tried to write a small routine to compute the EHS for some hands, but I keep getting inconsistent results. For example:
As imput: Hand: Ad Qc
Flop: 3h 4c Jh (like in "Opponent Modeling in Poker")
My result is:

[18:00:04] HS: 0.5851063829787234
[18:00:04] Ppot: 0.20844566061957367
[18:00:04] Npot: 0.27369265780332974
[18:00:04] EHS: 0.511449836010428

which seems to be correct, according to the paper named above.
But in http://www.poker-ai.org/archive/pokerai.org/pf3/viewtopic57d8.html?f=3&t=2764&view=next I saw some EHS values calculated by indiana, so I tried to verify my code with these value.

AsAd 4cJh9s --> EHS: 0.853 worked correct for me:
...
[18:04:46] EHS: 0.8530260981694839

But some inputs seem to result in wrong EHS values, just like:
AhJd JcJhAs --> EHS: 0.994

my results: EHS: 0.9881422924901185

Can you find any error in my code, except the quick and dirty style?
Code:
 Deck deck = new Deck();
        deck.shuffle();

        List<Card> d = deck.deal(52);
        Card[] de = d.toArray(new Card[d.size()]);

        int[] distribution = new int[3];

        int[][] HP = new int[3][3];
        int[] HPTotal = new int[3];
        int[] HPTotal_ = new int[3];
        int ind = 0;

        int index = 0, ahead = 0, tied = 1, behind = 2 ;
        Hand myHand = new Hand("Ah Jd");
        List<Card> board = new ArrayList<>();
        board.add(new Card("As"));
        board.add(new Card("Jc"));
        board.add(new Card("Jh"));

        for (int i = 0; i < de.length-1; i++) {
            Card o1 = de[i];
            if (board.contains(o1) || myHand.contains(o1)) {
                continue;
            }
           
            for (int j = i+1; j < de.length; j++) {
                Card o2 = de[j];
                if (board.contains(o2) || myHand.contains(o2) || o1.equals(o2)) {
                    continue;
                }
               
                //index++;
                Hand h1 = new Hand(board);
                h1.addCards(myHand.getCards());

                Hand h2 = new Hand(board);
                h2.addCard(o1);
                h2.addCard(o2);

                HandValue v1 = new HandValue(h1);
                HandValue v2 = new HandValue(h2);

//              System.out.println(index+": Checking "+ c1.toString()+ " "+c2.toString() +"-> "+ v1.getDescription()+"("+v1.getValue()+")"+ " vs. "+v2.getDescription()+"("+v2.getValue()+")");

                if (v1.getValue() > v2.getValue()) {
                    distribution[0]++;
                    index = ahead;
                } else if (v1.getValue() == v2.getValue()) {
                    distribution[1]++;
                    index = tied;
                } else if (v1.getValue() < v2.getValue()) {
                    distribution[2]++;
                    index = behind;
                }
               

                for (int k = 0; k < de.length; k++) {
                    Card turn = de[k];
                    if (board.contains(turn) || myHand.contains(turn) || o1.equals(turn) || o2.equals(turn)) {
                        continue;
                    }
                    for (int l = k; l < de.length; l++) {
                        Card river = de[l];
                        if (board.contains(river) || myHand.contains(river) || o1.equals(river) || o2.equals(river) || turn.equals(river)) {
                            continue;
                        }
                       
                        board.add(0,river);
                        board.add(0,turn);

                        h1 = new Hand(board);
                        h1.addCards(myHand.getCards());

                        h2 = new Hand(board);
                        //System.out.println(h2.toString());
                        board.remove(0);
                        board.remove(0);
                                             
                        h2.addCard(o1);
                        h2.addCard(o2);

                        v1 = new HandValue(h1);
                        v2 = new HandValue(h2);
//
//                     
                        if (v1.getValue() > v2.getValue()) {
                            HP[index][ahead] += 1;
                        } else if (v1.getValue() == v2.getValue()) {
                            HP[index][tied]  += 1;
                        } else if (v1.getValue() < v2.getValue()) {
                            HP[index][behind]+= 1;
                            //System.out.println(": Checking o1:"+ o1.toString()+ " o2:"+o2.toString() +"-> "+ v1.getDescription()+"("+h1.toString()+")"+ " vs. "+v2.getDescription()+"("+h2.toString()+")");
                            //System.out.println("Board: "+board);
                        }
                       
                        ind += 1;
                        //HPTotal_[index] =  HP[0][index]+HP[1][index]+HP[2][index];
                        HPTotal[index] =  HP[index][ahead]+HP[index][tied]+HP[index][behind];
                    }
                }

            }
        }

        for (int i = 0; i < distribution.length; i++) {
            System.out.println(distribution[i]);
        }
        double HS = ((double)distribution[ahead]+ (double)distribution[tied]/2);
        HS = HS  / ((double)distribution[ahead]+(double)distribution[tied]+(double)distribution[behind]);
        for (int i = 0; i < HP.length; i++) {
            System.out.println(HP[i][ahead]+"\t"+HP[i][tied]+"\t"+HP[i][behind]+"\t"+HPTotal[i]);
        }
       
        System.out.println("HS: "+HS);
        /* Ppot: were behind but moved ahead. */
       
        double Ppot = ((double)HP[behind][ahead]+(double)HP[behind][tied]/2.0 +(double)HP[tied][ahead]/2.0);
        if (Ppot != 0) Ppot /= ((double)HPTotal[behind]+(double)HPTotal[tied]/2.0);
        double Npot = ((double)HP[ahead][behind]+(double)HP[tied][behind]/2.0 +(double)HP[ahead][tied]/2.0) / ((double)HPTotal[ahead]+(double)HPTotal[tied]/2.0);
        double EHS  = HS + (1 - HS) * Ppot - HS * Npot;
       
        System.out.println("Ppot: "+Ppot);
        System.out.println("Npot: "+Npot);
        System.out.println("EHS: "+EHS);


Top
 Profile  
 
PostPosted: Mon Aug 26, 2013 4:27 am 
Offline
Veteran Member

Joined: Thu Feb 28, 2013 2:39 am
Posts: 437
Did they leave the HS * Npot on there? In the paper originally describing EHS they mentioned leaving off the negative potential.


Top
 Profile  
 
PostPosted: Mon Aug 26, 2013 6:37 am 
Offline
Junior Member

Joined: Sat Jun 29, 2013 1:43 am
Posts: 11
I have not used Indiana but have a few programs that do the same thing.

A player with a flop and random opponents means there are 1081 possible opponent hands.

For each of those opponents then you get 990 exhaustive trials, thus (1081 * 990) or 1070190 possible wins after going through all opponents. My array for wins show 1061122 out of the 1070190 thus .9915267 or 99.15%. Again that's just for wins.

What counts are you getting?

My logic loops through available hands that I have in a list after removing cards already taken so it only goes through the 1081 possible opponents. Maybe something is incorrect in getvalue().

Again I'm not familiar with Indiana but check your array counts first to see if one or both are off.


Top
 Profile  
 
PostPosted: Mon Aug 26, 2013 4:45 pm 
Offline
New Member

Joined: Thu May 30, 2013 11:49 am
Posts: 2
Nasher wrote:
Did they leave the HS * Npot on there? In the paper originally describing EHS they mentioned leaving off the negative potential.


That's right, the EHS calculation in the paper didn't used the HS * Npot, but the count of winning/tied/losing/ hands in my results are the same as in the paper, just like the HS, Ppot and Npot.
I used the EHS with negativ potential, because indiana used it for his results as well, so I can compare the results properly.

Below you find my results for AhJd-JcJhAs

Code:
5Cards-----------7Cards--------------------
--------------Ahead-----Tied---Behind---Total           
Ahead---------1056466---0------10754----1067220
Tied----------0---------1980---0--------1980
Behind--------44--------0------946------990


HS: 0.9981498612395929
Ppot: 0.022222222222222223
Npot: 0.010067308862489585
EHS: 0.9881422924901185

Another drastic example is AsAh-AdAcKh:


Code:
5Cards-----------7Cards--------------------
--------------Ahead-----Tied---Behind---Total           
Ahead---------1070178---0------12-------1070190
Tied----------0---------0------0--------0
Behind--------0---------0------0--------0


HS: 1.0
Ppot: 0.0
Npot: 1.1212962184285033E-5
EHS: 0.9999887870378157

I don't have indianas results for this combination, but the results seems to be correct, since there are only 12 combinations (straight flush) to lose vs. with this hand. Can someone verify those numbers?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group