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  [ 10 posts ] 
Author Message
PostPosted: Wed Apr 10, 2013 2:59 am 
Offline
Veteran Member

Joined: Wed Mar 20, 2013 1:43 am
Posts: 267
Code:
  public static double riverEquity(HoleCards hero, Range range, Board board) {
      double win = 0;
      double runs = 0;
      // VillainRange
      Range villainRange = range.cardRemoval(board.getBoardCards());
      villainRange = villainRange.cardRemoval(hero.getCard1());
      villainRange = villainRange.cardRemoval(hero.getCard2());
      // All boardcards
      LinkedList<Card> boardCards = board.getBoardCards();
      // u Values for the board in the lookup table
      int u0 = Generator.handRanks[53 + boardCards.get(0).getEval()];
      int u1 = Generator.handRanks[u0 + boardCards.get(1).getEval()];
      int u2 = Generator.handRanks[u1 + boardCards.get(2).getEval()];
      int u3 = Generator.handRanks[u2 + boardCards.get(3).getEval()];
      int u4 = Generator.handRanks[u3 + boardCards.get(4).getEval()];
      // heroValue
      int h1 = Generator.handRanks[u4 + hero.getCard1().getEval()];
      int h2 = Generator.handRanks[h1 + hero.getCard2().getEval()];

      for (HoleCards villainCards : villainRange) {
         // Villain Value
         int v1 = Generator.handRanks[u4 + villainCards.getCard1().getEval()];
         int v2 = Generator.handRanks[v1 + villainCards.getCard2().getEval()];
         System.out.print(h2 + "   ");
         System.out.println(v2);
         if (h2 > v2) {
            win++;
            runs++;
         } else if (h2 < v2) {
            runs++;
         } else {
            win = win + 0.5;
            runs++;
         }
      }
      return win / runs;
   }


getEval() returns the int Value for a card. I have doublechecked my implementation of getEval(), the int values were correct. The evaluator computes strange ranks, it also doesnt seem to recognize nut boards.


Top
 Profile  
 
PostPosted: Wed Apr 10, 2013 7:15 am 
Offline
Site Admin
User avatar

Joined: Thu Feb 28, 2013 5:24 pm
Posts: 230
What are handranks[] and getEval() supposed to do exactly?
I don't really understand what you are trying to do, seems to be a somewhat strange way to get the equity of one hand against all the remaining hands.

The way you should be using this is like this:
1) Input a 7 card hand into the evaluator (hero's holecards + board), get the rank.
2) Input another 7 card evaluator (villain's holecards + board), get the rank.
3) Compare both ranks to see which is higher, aka wins.

_________________
Cheers.


Top
 Profile  
 
PostPosted: Wed Apr 10, 2013 11:51 am 
Offline
Site Admin
User avatar

Joined: Sun Feb 24, 2013 9:39 pm
Posts: 642
- At a glance I don't see that you are doing much wrong.
- I don't have a lot of time to help you right now.
- I notice that you refer to Spears 2 + 2 Evaluator and Generator
- pokerai.game.eval.spears2p2 contains the class StateTableEvaluator
- pokerai.game.eval.twoplustwo contains the class Generator
- Generator and StateTableEvaluator use a different convention for card ids
- Maybe you are using the wrong card id?
- It would help if you could break the problem down further. eg generate the rank of a particular hand.


Top
 Profile  
 
PostPosted: Wed Apr 10, 2013 10:44 pm 
Offline
Junior Member
User avatar

Joined: Sun Mar 10, 2013 11:38 pm
Posts: 34
Don't forget that the returned integer is a 2-part binary which contains hand category and hand rank. You have to do a couple of bitwise operations to separate them:

http://www.codingthewheel.com/archives/ ... undup/#2p2

_________________
www.bespokebots.com


Top
 Profile  
 
PostPosted: Thu Apr 11, 2013 3:08 am 
Offline
Veteran Member

Joined: Wed Mar 20, 2013 1:43 am
Posts: 267
Coffee4tw wrote:
What are handranks[] and getEval() supposed to do exactly?
I don't really understand what you are trying to do, seems to be a somewhat strange way to get the equity of one hand against all the remaining hands.

The way you should be using this is like this:
1) Input a 7 card hand into the evaluator (hero's holecards + board), get the rank.
2) Input another 7 card evaluator (villain's holecards + board), get the rank.
3) Compare both ranks to see which is higher, aka wins.


getEval() returns the int conversion of my Card Object. I am representing cards as objects with a suit and a rank in my program, I dont use ints directly, so I need that method.

handRanks[] ist the LUT. I am inserting the 5 boardcards first, so I only need 2 lookups for every hand villain can hold.

I use this conversion:

2c = 1 2d = 14 2h = 27 2s = 40
3c = 2 3d = 15 3h = 28 3s = 41
4c = 3 4d = 16 4h = 29 4s = 42
5c = 4 5d = 17 5h = 30 5s = 43
6c = 5 6d = 18 6h = 31 6s = 44
7c = 6 7d = 19 7h = 32 7s = 45
8c = 7 8d = 20 8h = 33 8s = 46
9c = 8 9d = 21 9h = 34 9s = 47
Tc = 9 Td = 22 Th = 35 Ts = 48
Jc = 10 Jd = 23 Jh = 36 Js = 49
Qc = 11 Qd = 24 Qh = 37 Qs = 50
Kc = 12 Kd = 25 Kh = 38 Ks = 51
Ac = 13 Ad = 26 Ah = 39 As = 52

I also tried to split the handrank into 2 parts as described on CTW, but it still didnt work:

Code:
   public static double riverEquity(HoleCards hero, Range range, Board board) {
      double win = 0;
      double runs = 0;
      // VillainRange
      Range villainRange = range.cardRemoval(board.getBoardCards());
      villainRange = villainRange.cardRemoval(hero.getCard1());
      villainRange = villainRange.cardRemoval(hero.getCard2());
      // All boardcards
      LinkedList<Card> boardCards = board.getBoardCards();
      // u Values for the board in the lookup table
      int u0 = Generator.handRanks[53 + boardCards.get(0).getEval()];
      int u1 = Generator.handRanks[u0 + boardCards.get(1).getEval()];
      int u2 = Generator.handRanks[u1 + boardCards.get(2).getEval()];
      int u3 = Generator.handRanks[u2 + boardCards.get(3).getEval()];
      int u4 = Generator.handRanks[u3 + boardCards.get(4).getEval()];
      // heroValue
      int h1 = Generator.handRanks[u4 + hero.getCard1().getEval()];
      int h2 = Generator.handRanks[h1 + hero.getCard2().getEval()];
      

      for (HoleCards villainCards : villainRange) {
         // Villain Value
         int v1 = Generator.handRanks[u4 + villainCards.getCard1().getEval()];
         int v2 = Generator.handRanks[v1 + villainCards.getCard2().getEval()];
         //System.out.print(h2 + "   ");
         //System.out.println(v2);
         
         int handcategoryHero = h2>>12;
         int handcategoryVillain = v2>>12;
         int rankHero = h2&0x00000FFF;
         int rankVillain = v2 &0x00000FFF;
         //System.out.println(handcategoryHero);
         //System.out.println(handcategoryVillain);
         if (handcategoryHero > handcategoryVillain) {
            System.out.println(hero);
            System.out.println(villainCards);
            win++;
            runs++;
         } else if (handcategoryHero<handcategoryVillain) {
            runs++;
         } else {
            if(rankHero > rankVillain){
               win++;
               runs++;
            }
            else if(rankHero < rankVillain){
               runs++;
            }
            else{
               win = win + 0.5;
               runs++;
            }
         }
      }
      return win / runs;
   }


On a Ad Ac Th 4c 2c board I get 8393 for a AhAs hand and 8248 for a 5d5h hand.


Top
 Profile  
 
PostPosted: Thu Apr 11, 2013 7:59 pm 
Offline
Junior Member
User avatar

Joined: Sun Mar 10, 2013 11:38 pm
Posts: 34
Your string to integer conversions are wrong. In Python, the lookup dict is this:
Code:
{
    'str_to_int':
        {
            '2c': 1, '2d': 2, '2h': 3, '2s': 4,
            '3c': 5, '3d': 6, '3h': 7, '3s': 8,
            '4c': 9, '4d': 10, '4h': 11, '4s': 12,
            '5c': 13, '5d': 14, '5h': 15, '5s': 16,
            '6c': 17, '6d': 18, '6h': 19, '6s': 20,
            '7c': 21, '7d': 22, '7h': 23, '7s': 24,
            '8c': 25, '8d': 26, '8h': 27, '8s': 28,
            '9c': 29, '9d': 30, '9h': 31, '9s': 32,
            'Tc': 33, 'Td': 34, 'Th': 35, 'Ts': 36,
            'Jc': 37, 'Jd': 38, 'Jh': 39, 'Js': 40,
            'Qc': 41, 'Qd': 42, 'Qh': 43, 'Qs': 44,
            'Kc': 45, 'Kd': 46, 'Kh': 47, 'Ks': 48,
            'Ac': 49, 'Ad': 50, 'Ah': 51, 'As': 52
        },
    'int_to_str':
        {
            1: '2c', 2: '2d', 3: '2h', 4: '2s',
            5: '3c', 6: '3d', 7: '3h', 8: '3s',
            9: '4c', 10: '4d', 11: '4h', 12: '4s',
            13: '5c', 14: '5d', 15: '5h', 16: '5s',
            17: '6c', 18: '6d', 19: '6h', 20: '6s',
            21: '7c', 22: '7d', 23: '7h', 24: '7s',
            25: '8c', 26: '8d', 27: '8h', 28: '8s',
            29: '9c', 30: '9d', 31: '9h', 32: '9s',
            33: 'Tc', 34: 'Td', 35: 'Th', 36: 'Ts',
            37: 'Jc', 38: 'Jd', 39: 'Jh', 40: 'Js',
            41: 'Qc', 42: 'Qd', 43: 'Qh', 44: 'Qs',
            45: 'Kc', 46: 'Kd', 47: 'Kh', 48: 'Ks',
            49: 'Ac', 50: 'Ad', 51: 'Ah', 52: 'As'
        }
}


FYI:
'AhAs' = [51, 52]
'AdAcTh4c2c' = [50, 49, 35, 9, 1]
hand_rank = 32921 = [8, 153]

_________________
www.bespokebots.com


Top
 Profile  
 
PostPosted: Fri Apr 12, 2013 12:00 am 
Offline
Senior Member

Joined: Mon Mar 11, 2013 10:24 pm
Posts: 216
Given the discussion here, I was taking a look into changing my HandEvaluator (Steve Brecher's) with the Spears 2+2 one. Performing a speed test showed however weird results when comparing them to the evaluation thread. Here's how I compared the two approaches:


1. Generate 100k random 7 card hands
2. Generate a list with int[] of all boards using the 2+2 coding
3. Generate a list with long of all boards using the Brecher coding
4. Initialize the 2+2 Evaluator.

Now for each Evaluator, I run a loop 1000 times where it iterates over all coded hands (lists generated in step 2/3) and take the time. So in total, 1000 * 100000 = 100M hands are evaluated.

Here are the times in milliseconds:
2+2: 14773
Brecher: 2228

I'm not sure why 2+2 is so much slower than expected and also why Brecher's code is very fast compared to the Evaluation results (though it might be due to different test hardware). Anyone notices a flaw in the comparison of the 2 approaches?


Top
 Profile  
 
PostPosted: Fri Apr 12, 2013 6:03 am 
Offline
Site Admin
User avatar

Joined: Sun Feb 24, 2013 9:39 pm
Posts: 642
@birchy Thanks for sorting that out

@p2bb There are two variants of the 2+2 evaluator in the distribution:
- pokerai/game/eval/twoplustwo is ugly and fast (1) in http://www.poker-ai.org/archive/www.pok ... l?f=3&t=16)
- pokerai/game/eval/spears2p2 is pretty but slow (4) in http://www.poker-ai.org/archive/www.pok ... l?f=3&t=16

pokerai/game/eval/twoplustwo runs quickly when the hands are ordered like this:
6d 3s 8h 9c Ah 3h 2c
6d 3s 8h 9c Ah 3h 3c
6d 3s 8h 9c Ah 3h 4c
6d 3s 8h 9c Ah 3h 5c
...
6d 3s 8h 9c Ah 4h 2c
6d 3s 8h 9c Ah 4h 3c
6d 3s 8h 9c Ah 4h 4c

... but slowly when hands are submitted randomly. If you take a look at HontoNiBaka's code above, the reason should be clear.


Top
 Profile  
 
PostPosted: Fri Apr 12, 2013 3:30 pm 
Offline
Senior Member

Joined: Mon Mar 11, 2013 10:24 pm
Posts: 216
Ahhh, thanks. I took the slow one - but it was pretty indeed ;) Now I'll check out quasimodo...


Top
 Profile  
 
PostPosted: Wed Aug 21, 2013 8:40 am 
Offline
New Member

Joined: Wed Aug 21, 2013 8:36 am
Posts: 2
I remember 2p2 7eval had bugs which I was bitten by in the past. I am not 100% sure it was this one (it was one with code pasted in one of the 2p2 threads). There was Python one as well which also was buggy.
I switched to Brecher's eval for everything and I love it.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 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