Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/pokersource/enum/SAIE.java


1   // $Id: SAIE.java,v 1.7 2002/06/13 03:04:56 mjmaurer Exp $
2   
3   package org.pokersource.enum;
4   import org.pokersource.game.Deck;
5   import java.util.Map;
6   import java.util.Iterator;
7   import java.util.Enumeration;
8   
9   /** Algorithms for computing subjective all-in equity.  SAIE is a player's pot
10      equity given particular beliefs about the possible hands of the
11      opponent(s) and assuming no further betting.  Beliefs about an opponent's
12      hand distribution are represented by a BeliefVector object which maps each
13      possible opponent hand to the probability of its occurrence.
14      @author Michael Maurer <mjmaurer@yahoo.com>
15  */
16  
17  public class SAIE {
18  
19    /** Compute the subjective all-in equity of each player based on a
20        belief distribution for each player's hands.  Typical usage is
21        to fix one player's cards and allow the other players' cards to
22        range over a distribution; however, it is valid for all players to
23        have multiple possible hands.
24        @param gameType One of Enumerate.GAME_HOLDEM, etc.
25        @param nmatchups number of matchups to sample (if zero, full enumeration)
26        [Note: matchups are counted before they are tested for feasibility, that
27        is, whether they share cards.  So the total number of matchups that
28        contribute to the SAIE estimate may be less than nmatchups.]
29        @param noutcomes number of boards to sample (if zero, full enumeration)
30        @param handDistribs the hand distribution belief vector for each player
31        @param board bitmask of cards already dealt to board (can be zero)
32        @param dead bitmask of cards that cannot appear in any hand or on
33        the board (can be zero)
34        @param ev output: ev[i] player i's all-in pot equity
35        @param matchups output: map of {HandMatchup, MatchupOutcome}
36        pairs, one for each matchup
37    */
38    public static void FlopGameSAIE(int gameType,
39                                    int nmatchups, int noutcomes,
40                                    BeliefVector[] handDistribs,
41                                    long board, long dead,
42                                    double ev[], Map matchups) {
43      if (matchups != null)
44        matchups.clear();
45      int nplayers = handDistribs.length;
46      long[][] hands = new long[nplayers][];
47      int[] nhands = new int[nplayers];
48      for (int i=0; i<nplayers; i++) {
49        hands[i] = handDistribs[i].getHands();
50        nhands[i] = hands[i].length;
51        ev[i] = 0;
52      }
53      long unavail1 = dead | board;
54      double totalprob = 0;
55      double[] matchev = new double[nplayers];
56      long[] curhands = new long[nplayers];
57      Enumeration enum;
58      if (nmatchups == 0) {
59        enum = new NestedLoopEnumeration(nhands);
60      } else {
61        enum = new NestedLoopSampling(nhands, nmatchups);
62      }
63    mainloop:
64      while (enum.hasMoreElements()) { // loop over all hand matchups
65        int[] indices = (int[]) enum.nextElement();
66        long unavail2 = unavail1;
67        double matchprob = 1;     // the probability of this matchup
68        for (int i=0; i<nplayers; i++) {
69          // get a particular hand for each player to use in this matchup
70          curhands[i] = hands[i][indices[i]];
71          if ((curhands[i] & unavail2) != 0) // already used one of these cards?
72            continue mainloop;         // if so, this matchup cannot occur
73          unavail2 |= curhands[i];
74          matchprob *= handDistribs[i].getBeliefProb(curhands[i]);
75          if (matchprob == 0)
76            continue mainloop;
77        }
78  
79        // heavy lifting for this matchup: enumerate all outcomes
80        Enumerate.PotEquity(gameType, noutcomes, curhands, board, dead, matchev);
81  
82        if (matchups != null) { // save to Collection if requested
83          HandMatchup matchup = new HandMatchup(curhands);
84          MatchupOutcome outcome = new MatchupOutcome(matchprob, matchev);
85          MatchupOutcome existing = (MatchupOutcome) matchups.get(matchup);
86          if (existing != null)
87            existing.merge(outcome);
88          else
89            matchups.put(matchup, outcome);
90        }
91  
92        // accumulate this matchup into totals
93        for (int i=0; i<nplayers; i++)
94          ev[i] += matchev[i] * matchprob;
95        totalprob += matchprob;
96      }
97      if (totalprob == 0)
98        throw new IllegalArgumentException("no matchups sampled: increase nmatchups?");
99      // Scale by the total probability of all matchups (this factor is less
100     // than one when the hand distributions are not disjoint).
101     for (int i=0; i<nplayers; i++)
102       ev[i] /= totalprob;
103     if (matchups != null) {
104       for (Iterator iter=matchups.values().iterator(); iter.hasNext(); ) {
105         MatchupOutcome outcome = (MatchupOutcome) iter.next();
106         outcome.matchProb /= totalprob;
107       }
108     }
109   }
110 
111   public static void main(String[] args) {
112     int nmatchups = Integer.parseInt(args[0]);
113     int noutcomes = Integer.parseInt(args[1]);
114     int nplayers = args.length - 4;
115     System.out.println("nplayers=" + nplayers + 
116                        ", nmatchups=" + nmatchups +
117                        ((nmatchups == 0) ? " (enumerate)" : " (sample)") +
118                        ", noutcomes=" + noutcomes +
119                        ((noutcomes == 0) ? " (enumerate)" : " (sample)"));
120     HoldemBeliefVector[] beliefs = new HoldemBeliefVector[nplayers];
121     for (int i=0; i<nplayers; i++) {
122       beliefs[i] = new HoldemBeliefVector(args[i+2]);
123       System.out.println("beliefs[" + i + "].toString = " +
124                          beliefs[i].toString());
125       System.out.println("beliefs[" + i + "].toStringAtomic = " +
126                          beliefs[i].toStringAtomic());
127     }
128     long board = Deck.parseCardMask(args[args.length-2]);
129     long dead = Deck.parseCardMask(args[args.length-1]);
130     System.out.println("board = " + Deck.cardMaskString(board));
131     System.out.println("dead = " + Deck.cardMaskString(dead));
132 
133     double[] totalev = new double[nplayers];
134     FlopGameSAIE(Enumerate.GAME_HOLDEM, nmatchups, noutcomes,
135                  beliefs, board, dead, totalev, null);
136     for (int i=0; i<nplayers; i++) {
137       System.out.println("FlopGameSAIE: totalev[" + i + "] = " + totalev[i]);
138     }
139   }
140 }