Permalink
Browse files

Initial commit

  • Loading branch information...
adamsmith committed Jan 19, 2013
1 parent cb10cb8 commit 6fa9d57ffb25b1b3bf9d714d26f0d4691881436b
Showing with 12,018 additions and 2 deletions.
  1. +152 −2 README.md
  2. BIN misc/Meerkat-API.zip
  3. BIN misc/game tree - detailed.ppt
  4. BIN misc/game tree - high level.ppt
  5. +128 −0 src/_game/Card.java
  6. +219 −0 src/_io/BurstBufferedReader.java
  7. +121 −0 src/_io/BurstBufferedWriter.java
  8. +77 −0 src/_io/ReadBinaryClusterIdStream.java
  9. +90 −0 src/_io/ReadBinaryClusterIdTableStream.java
  10. +61 −0 src/_io/ReadBinaryConstraintMatrix.java
  11. +21 −0 src/_io/ReadBinaryData.java
  12. +57 −0 src/_io/ReadBinaryNameMap.java
  13. +70 −0 src/_io/ReadBinaryRm.java
  14. +110 −0 src/_io/ReadBinaryRmStream.java
  15. +93 −0 src/_io/ReadBinaryScoreGroupStream.java
  16. +71 −0 src/_io/ReadBinaryScoreMaps.java
  17. +109 −0 src/_io/ReadBinaryScoreMapsStream.java
  18. +96 −0 src/_io/ReadBinaryScoreStream.java
  19. +66 −0 src/_io/ReadBinarySolutionMap.java
  20. +51 −0 src/_io/ReadBinaryStartClusterPDT.java
  21. +62 −0 src/_io/ReadBinarySubtreeGame.java
  22. +51 −0 src/_io/ReadBinaryTerminalClusterValues.java
  23. +56 −0 src/_io/ReadBinaryTransitionPDT.java
  24. +65 −0 src/_io/WriteBinaryActionWeightList.java
  25. +73 −0 src/_io/WriteBinaryClusterIDStream.java
  26. +67 −0 src/_io/WriteBinaryClusterIDTableStream.java
  27. +70 −0 src/_io/WriteBinaryConstraintMatrix.java
  28. +73 −0 src/_io/WriteBinaryNameList.java
  29. +64 −0 src/_io/WriteBinaryNameMap.java
  30. +77 −0 src/_io/WriteBinaryRmeStream.java
  31. +75 −0 src/_io/WriteBinaryScoreGroupStream.java
  32. +100 −0 src/_io/WriteBinaryScoreMaps.java
  33. +86 −0 src/_io/WriteBinaryScoreStream.java
  34. +64 −0 src/_io/WriteBinarySolutionMap.java
  35. +59 −0 src/_io/WriteBinaryStartClusterPDT.java
  36. +63 −0 src/_io/WriteBinarySubtreeGame.java
  37. +59 −0 src/_io/WriteBinaryTerminalClusterValues.java
  38. +65 −0 src/_io/WriteBinaryTransitionPDT.java
  39. +215 −0 src/_io/WriteMPS.java
  40. +10 −0 src/_io/beans/StartClusterBean.java
  41. +37 −0 src/_misc/ByteArrayWrapper.java
  42. +153 −0 src/_misc/Combinations.java
  43. +96 −0 src/_misc/Combinatoric.java
  44. +94 −0 src/_misc/Constants.java
  45. +273 −0 src/_misc/Helper.java
  46. +130 −0 src/stage1/DoBacktracking.java
  47. +151 −0 src/stage1/DoShowdowns.java
  48. +233 −0 src/stage1/HandEvaluator.java
  49. +47 −0 src/stage1/HandRecord.java
  50. +33 −0 src/stage1/HandRecordClusterId.java
  51. +33 −0 src/stage1/HandRecordScore.java
  52. +38 −0 src/stage1/HandRecordScoreGroups.java
  53. +68 −0 src/stage1/HandRecordScoreMap.java
  54. +22 −0 src/stage1/README.txt
  55. +224 −0 src/stage1/ScoreMaps.java
  56. +212 −0 src/stage1/test.java
  57. +114 −0 src/stage1/testHandEvaluator.java
  58. +328 −0 src/stage2/ClustererStream.java
  59. +177 −0 src/stage2/DoClusteringStep1.java
  60. +342 −0 src/stage2/DoClusteringStep2.java
  61. +157 −0 src/stage2/DoStartClusterPDT.java
  62. +185 −0 src/stage2/DoTerminalClusterValuesStep1.java
  63. +137 −0 src/stage2/DoTerminalClusterValuesStep2.java
  64. +278 −0 src/stage2/DoTransitionPDTStep1.java
  65. +176 −0 src/stage2/DoTransitionPDTStep2.java
  66. +26 −0 src/stage2/ListOfArraysComparator.java
  67. +39 −0 src/stage2/README.txt
  68. +98 −0 src/stage2/TestHandClustering.java
  69. +35 −0 src/stage2/Touple/IntTouple.java
  70. +32 −0 src/stage2/Touple/ToupleFloatComparator.java
  71. +28 −0 src/stage2/Touple/ToupleFloatInt.java
  72. +32 −0 src/stage2/Touple/ToupleIntComparator.java
  73. +33 −0 src/stage2/TransitionPDT.java
  74. +117 −0 src/stage3/Agenda.java
  75. +163 −0 src/stage3/ConstraintMatrix.java
  76. +42 −0 src/stage3/ConstraintMatrixColumn.java
  77. +70 −0 src/stage3/ConstraintMatrixRow.java
  78. +220 −0 src/stage3/DoGT.java
  79. +198 −0 src/stage3/DoParseClpOutput.java
  80. +449 −0 src/stage3/DoPreprocessRm.java
  81. +448 −0 src/stage3/DoSubtreeGames.java
  82. +281 −0 src/stage3/DoWriteLP.java
  83. +332 −0 src/stage3/GameState.java
  84. +89 −0 src/stage3/InfoSet/InfoString.java
  85. +211 −0 src/stage3/InfoSet/InfoToken.java
  86. +85 −0 src/stage3/InterpretMPS.java
  87. +112 −0 src/stage3/LoadInputData.java
  88. +80 −0 src/stage3/NameMap.java
  89. +15 −0 src/stage3/README.txt
  90. +86 −0 src/stage3/RewardMatrixElement.java
  91. +156 −0 src/stage4/ClusterIdResolver.java
  92. +148 −0 src/stage4/DoConvertSolsForRndAccess.java
  93. +488 −0 src/stage4/MeerkatPlayer.java
  94. +182 −0 src/stage4/WeightResolver.java
  95. +29 −0 src/stage4/build.xml
  96. +74 −0 src/unused/CorrectBeginningOffset.java
  97. +75 −0 src/unused/PivotTextOntoHandCards.java
  98. +108 −0 src/unused/stage3/BettingRound.java
  99. +36 −0 src/unused/stage3/ChanceRound.java
  100. +28 −0 src/unused/stage3/ContinueItem.java
  101. +106 −0 src/unused/stage3/DoPreprocessRm.java
  102. +48 −0 src/unused/stage3/GameTree/BeginRoundChoiceNode.java
  103. +54 −0 src/unused/stage3/GameTree/ChanceNode.java
  104. +17 −0 src/unused/stage3/GameTree/ChoiceNode.java
  105. +43 −0 src/unused/stage3/GameTree/EndRoundChoiceNode.java
  106. +49 −0 src/unused/stage3/GameTree/MiddleRoundChoiceNode.java
  107. +48 −0 src/unused/stage3/GameTree/Node.java
  108. +32 −0 src/unused/stage3/GameTree/RootNode.java
  109. +35 −0 src/unused/stage3/GameTree/TerminalLeafNode.java
  110. +58 −0 src/unused/stage3/InfoSet/InfoSet.java
  111. +52 −0 src/unused/stage3/InfoSet/InfoSetPair.java
  112. +47 −0 src/unused/stage3/InfoSet/InfoTokenArrWrapper.java
View
154 README.md
@@ -1,4 +1,154 @@
game-theory-poker
-=================
+=====
-A game-theoretic poker player (written in 2005)
+This is a game-theoretic, heads-up limit Texas Hold'em poker player I wrote in 2005, based on the paper [_Approximating Game-Theoretic Optimal Strategies for Full-scale Poker_](https://www.google.com/search?q=Approximating+Game-Theoretic+Optimal+Strategies+for+Full-scale+Poker). It's about 6,000 lines of Java.
+
+
+### Theory of Operation
+Playing the optimal strategy for any game guarantees that you'll achieve at least the expected value of that game. In poker, assuming no rake, the expected value is zero, so if you can compute the optimal strategy then you're _guaranteed_ not to lose on average.
+
+Consider rock-paper-scissors. The optimal strategy for that game is to throw `rock` 1/3'rd of the time, `paper` 1/3'rd, and `scissors` 1/3'rd. If you play by this strategy you are guaranteed not to lose on average, regardless of what strategy your opponent plays by. (Note that even if your opponent throws `rock` every time, you'll still just tie (not lose) on average. But there are other games where the optimal strategy can dominate some opponents' strategies, and poker is one of them.)
+
+It's just too hard to compute the optimal strategy for poker, even two player limit poker. But we can compute the optimal strategy for an abstract version of poker that, for example, during pre-flop betting treats pairs of aces the same way as pairs of kings.
+
+This code computes the optimal strategy for an abstraction of poker that it builds based on the strength of different hands in different situations.
+
+A more detailed description of this idea is given in the paper _Approximating Game-Theoretic Optimal Strategies for Full-scale Poker_ (Billings, 2003).
+
+
+### How Good Is It?
+Okay, so how good is the resulting player? Well, you can tweak how abstract the game should be at each stage. The less abstract the game, the better the player will be, but you'll hit computation and memory constraints.
+
+The furthest I got was computing five clusters worth of representation for each turn. This took about a month to compute using three machines in my apartment living room. As a median-skilled poker player I could beat the resulting player, but not that easily.
+
+
+### Opportunities For Improvement
+Our abstraction of the game is fairly coarse. We can build a less abstract version of the game by leveraging the dramatic reduction in game size post-flop. The whole game tree has 10^18 nodes, but after you have your two hole cards and after the flop, there are just three rounds of betting and (47 choose 2) more cards that are coming. It's possible to compute the _exact_ optimal strategy for such a narrowed-down game.
+
+So what we should do is: for every (52 choose 2) * (50 choose 3) combination of post-flop states, compute the exact optimal strategy. Each result will also tell you the expected value of that sub-game. Then you compute the starting strategy for each (52 choose 2) initial states substituting the expected value from the sub-games as terminal nodes in the game tree.
+
+This isn't an exact version of the game, but it's _far_ better.
+
+The problem is it'd take about 400,000 CPU-hours to compute.
+
+So I started working on this during MIT's Independent Activities Period in January 2006, but I never finished the code. I stopped because classes started, but also because I didn't have access to 400k cpu-hours. (Coincidentally, I now have access to that kind of compute through [Gridspot](http://gridspot.com/compute), but alas working on this is no longer feasible given my opportunity costs.)
+
+
+### Notes On Using The Code
+* All calculations are done up-front. The resulting multi-gigabyte files fully specify the game strategies, so the actual player just has to do a few disk reads to know what to do at each turn.
+* Each step creates new data files that are used in later steps. There are 16 types of files all-in-all.
+* All of this code is written to process data sequentially, so that you can compute a multi-gigabyte strategy with comparatively little memory.
+* If you want to play around with this code you can compute a strategy for reduced version of poker. For example, the code defaults to computing the strategy for 14-card poker (2 suits, 7 card ranks). Use `_game.Cards` to control the parameters of the poker game you're computing for (_eg_ 14 versus 52 card poker) and how many clusters you want at each turn.
+
+
+### Usage Instructions
+1. Compute showdown rankings
+ * You should configure `Constants.DATA_FILE_REPOSITORY` first and create the subdirectory `{{ GAME_NAME }}/5`, before running.
+ * Run `stage1.DoShowdowns`
+
+
+1. Create files sorted on hole cards, and counts of `winCounts` (`+ tiecount / 2`) for hole cards during pre-flop, post-flop, post-turn, plus a new data format
+ * Run `stage1.DoBacktracking`
+
+
+1. Calculate clustering into abstract game
+ * Create `stage2` directory in `{{ GAME_NAME }}` subdir
+ * Run `stage2.DoClusteringStep1` with command line argument `0`
+ * Run `stage2.DoClusteringStep2` with command line arguments `0 5`
+
+
+1. Calculate transition probabilities for abstract game
+ * Run `stage2.DoStartClusterPDT`
+ * Run `stage2.DoTransitionPDTStep1 0 5`
+ * Run `stage2.DoTransitionPDTStep2 5`
+ * Run `stage2.DoTerminalClusterValuesStep1`
+ * Run `stage2.DoTerminalClusterValuesStep2`
+
+
+1. Construct game tree, convert game tree to sequence form (single pass), solve sequence form LP problem
+ * Run `stage3.DoGT root`
+ * Run `stage3.DoPreprocessRm mem-heavy root`
+ * Run `stage3.DoWriteLP root`
+ * from `{{ GAME_NAME }}\stage3\root`, run `bpmpd game.p1.mps` and `bpmpd game.p2.mps`
+ * the last few steps overlap with the first few steps in the following script, which executes everything else needed to get to the MeerkatPlayer. (Meerkat is a poker player API.) In the steps below, `/net1/poker/poker_data` is the `Constants.DATA_FILE_REPOSITORY`, and `52-5-1.1` is the `{{ GAME_NAME }}`. `bpmpd` resides in `/net1`.
+ * note that there are other LP-solvers available. I just happened to use bpmpd. The MPS file format is supported by most.
+
+ ```
+ java -Xms400M -Xmx1700M -Xincgc -classpath bin stage3.DoPreprocessRm mem-heavy root
+ java -Xms400M -Xmx1700M -Xincgc -classpath bin stage3.DoWriteLP root
+ cd /net1/bpmpd
+ ln -s /net1/poker/poker_data/52-5-1.1/stage3/root/game.p1.mps rootp1.mps
+ ln -s /net1/poker/poker_data/52-5-1.1/stage3/root/game.p2.mps rootp2.mps
+ rm -f *.out
+ ./bpmpd rootp1
+ cp rootp1.out /net1/poker/poker_data/52-5-1.1/stage3/root/game.p1.sol
+ ./bpmpd rootp2
+ cp rootp2.out /net1/poker/poker_data/52-5-1.1/stage3/root/game.p2.sol
+ cd /net1/poker
+ java -Xms400M -Xmx1700M -Xincgc -classpath bin stage3.DoParseClpOutput root
+ java -Xms400M -Xmx1700M -Xincgc -classpath bin stage3.DoSubtreeGames
+ java -Xms400M -Xmx1700M -Xincgc -classpath bin stage3.DoGT all-subtrees
+ java -Xms400M -Xmx1700M -Xincgc -classpath bin stage3.DoPreprocessRm mem-heavy all-subtrees
+ java -Xms400M -Xmx1700M -Xincgc -classpath bin stage3.DoWriteLP all-subtrees
+ cd /net1/bpmpd
+ rm -f ???.mps
+ ln -s /net1/poker/poker_data/52-5-1.1/stage3/a/game.p1.mps ap1.mps
+ ln -s /net1/poker/poker_data/52-5-1.1/stage3/a/game.p2.mps ap2.mps
+ ln -s /net1/poker/poker_data/52-5-1.1/stage3/b/game.p1.mps bp1.mps
+ ln -s /net1/poker/poker_data/52-5-1.1/stage3/b/game.p2.mps bp2.mps
+ ln -s /net1/poker/poker_data/52-5-1.1/stage3/c/game.p1.mps cp1.mps
+ ln -s /net1/poker/poker_data/52-5-1.1/stage3/c/game.p2.mps cp2.mps
+ ln -s /net1/poker/poker_data/52-5-1.1/stage3/d/game.p1.mps dp1.mps
+ ln -s /net1/poker/poker_data/52-5-1.1/stage3/d/game.p2.mps dp2.mps
+ ln -s /net1/poker/poker_data/52-5-1.1/stage3/e/game.p1.mps ep1.mps
+ ln -s /net1/poker/poker_data/52-5-1.1/stage3/e/game.p2.mps ep2.mps
+ ln -s /net1/poker/poker_data/52-5-1.1/stage3/f/game.p1.mps fp1.mps
+ ln -s /net1/poker/poker_data/52-5-1.1/stage3/f/game.p2.mps fp2.mps
+ ln -s /net1/poker/poker_data/52-5-1.1/stage3/g/game.p1.mps gp1.mps
+ ln -s /net1/poker/poker_data/52-5-1.1/stage3/g/game.p2.mps gp2.mps
+ rm -f *.out
+ ./bpmpd ap1
+ ./bpmpd ap2
+ ./bpmpd bp1
+ ./bpmpd bp2
+ ./bpmpd cp1
+ ./bpmpd cp2
+ ./bpmpd dp1
+ ./bpmpd dp2
+ ./bpmpd ep1
+ ./bpmpd ep2
+ ./bpmpd fp1
+ ./bpmpd fp2
+ ./bpmpd gp1
+ ./bpmpd gp2
+ cp ap1.out /net1/poker/poker_data/52-5-1.1/stage3/a/game.p1.sol
+ cp ap2.out /net1/poker/poker_data/52-5-1.1/stage3/a/game.p2.sol
+ cp bp1.out /net1/poker/poker_data/52-5-1.1/stage3/b/game.p1.sol
+ cp bp2.out /net1/poker/poker_data/52-5-1.1/stage3/b/game.p2.sol
+ cp cp1.out /net1/poker/poker_data/52-5-1.1/stage3/c/game.p1.sol
+ cp cp2.out /net1/poker/poker_data/52-5-1.1/stage3/c/game.p2.sol
+ cp dp1.out /net1/poker/poker_data/52-5-1.1/stage3/d/game.p1.sol
+ cp dp2.out /net1/poker/poker_data/52-5-1.1/stage3/d/game.p2.sol
+ cp ep1.out /net1/poker/poker_data/52-5-1.1/stage3/e/game.p1.sol
+ cp ep2.out /net1/poker/poker_data/52-5-1.1/stage3/e/game.p2.sol
+ cp fp1.out /net1/poker/poker_data/52-5-1.1/stage3/f/game.p1.sol
+ cp fp2.out /net1/poker/poker_data/52-5-1.1/stage3/f/game.p2.sol
+ cp gp1.out /net1/poker/poker_data/52-5-1.1/stage3/g/game.p1.sol
+ cp gp2.out /net1/poker/poker_data/52-5-1.1/stage3/g/game.p2.sol
+ cd /net1/poker
+ java -Xms400M -Xmx1700M -Xincgc -classpath bin stage3.DoParseClpOutput all-subtrees
+ ```
+
+
+1. Build your player data files around the resulting mixed strategy
+ * Run `stage4.DoConvertSolsForRndAccess root`
+ * Run `stage4.DoConvertSolsForRndAccess all-subtrees`
+
+1. Use your player
+ * Use the `stage4.MeerkatPlayer` class
+ * I originally used the player in PokerAcademy but it now seems that there are open source platforms that can use Meerkat players.
+
+
+### License
+
+This code is released under the public domain / no license.
View
Binary file not shown.
Binary file not shown.
Binary file not shown.
View
@@ -0,0 +1,128 @@
+package _game;
+
+
+
+
+public class Card {
+
+ // 52
+// public final static String GAME_NAME = "52-card holdem";
+// public final static byte NUM_SUITS = 4;
+// public final static byte NUM_RANKS = 13;
+// public final static byte NUM_CARDS = NUM_SUITS * NUM_RANKS; //52
+// public final static int ACE = NUM_RANKS - 1; // for normal deck ACE=12 (TWO=0)
+// public static final byte[] ALLCARDSINDEX = new byte[] {
+// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+// 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+// 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+// 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+// 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+// 51};
+// public final static byte[] NUM_CLUSTERS = new byte[] {7, -1, -1, 7, 7, 7};
+
+// // 52
+// public final static String GAME_NAME = "52-card holdem lite6";
+// public final static byte NUM_SUITS = 4;
+// public final static byte NUM_RANKS = 13;
+// public final static byte NUM_CARDS = NUM_SUITS * NUM_RANKS; //52
+// public final static int ACE = NUM_RANKS - 1; // for normal deck ACE=12 (TWO=0)
+// public static final byte[] ALLCARDSINDEX = new byte[] {
+// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+// 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+// 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+// 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+// 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+// 51};
+// public final static byte[] NUM_CLUSTERS = new byte[] {6, -1, -1, 6, 6, 6};
+
+ // 52
+// public final static String GAME_NAME = "52-card holdem lite5";
+// public final static byte NUM_SUITS = 4;
+// public final static byte NUM_RANKS = 13;
+// public final static byte NUM_CARDS = NUM_SUITS * NUM_RANKS; //52
+// public final static int ACE = NUM_RANKS - 1; // for normal deck ACE=12 (TWO=0)
+// public static final byte[] ALLCARDSINDEX = new byte[] {
+// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+// 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+// 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+// 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+// 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+// 51};
+// public final static byte[] NUM_CLUSTERS = new byte[] {5, -1, -1, 5, 5, 5};
+
+ // 52
+// public final static String GAME_NAME = "52-5-1.1";
+// public final static byte NUM_SUITS = 4;
+// public final static byte NUM_RANKS = 13;
+// public final static byte NUM_CARDS = NUM_SUITS * NUM_RANKS; //52
+// public final static int ACE = NUM_RANKS - 1; // for normal deck ACE=12 (TWO=0)
+// public static final byte[] ALLCARDSINDEX = new byte[] {
+// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+// 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+// 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+// 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+// 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+// 51};
+// public final static byte[] NUM_CLUSTERS = new byte[] {5, -1, -1, 5, 5, 5};
+
+
+ // 24
+// public final static String GAME_NAME = "24-card holdem";
+// public final static byte NUM_SUITS = 2;
+// public final static byte NUM_RANKS = 12;
+// public final static byte NUM_CARDS = NUM_SUITS * NUM_RANKS; //14
+// public final static int ACE = NUM_RANKS - 1; // for normal deck ACE=12 (TWO=0)
+// public final static byte[] ALLCARDSINDEX = new byte[] {
+// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+// 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+// 21, 22, 23};
+// public final static byte[] NUM_CLUSTERS = new byte[] {7, -1, -1, 7, 7, 7};
+
+
+ // 24-lite
+// public final static String GAME_NAME = "24-card holdem lite";
+// public final static byte NUM_SUITS = 2;
+// public final static byte NUM_RANKS = 12;
+// public final static byte NUM_CARDS = NUM_SUITS * NUM_RANKS; //14
+// public final static int ACE = NUM_RANKS - 1; // for normal deck ACE=12 (TWO=0)
+// public final static byte[] ALLCARDSINDEX = new byte[] {
+// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+// 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+// 21, 22, 23};
+// public final static byte[] NUM_CLUSTERS = new byte[] {3, -1, -1, 3, 3, 3};
+
+
+ // 14
+ public final static String GAME_NAME = "14-card holdem";
+ public final static byte NUM_SUITS = 2;
+ public final static byte NUM_RANKS = 7;
+ public final static byte NUM_CARDS = NUM_SUITS * NUM_RANKS; //14
+ public final static int ACE = NUM_RANKS - 1; // for normal deck ACE=12 (TWO=0)
+ public static final byte[] ALLCARDSINDEX = new byte[] {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13};
+ public final static byte[] NUM_CLUSTERS = new byte[] {3, -1, -1, 3, 3, 3};
+
+
+
+}
+
+
+
+/* fully explicit card to integer conversions :
+
+2c = 0 2d = 13 2h = 26 2s = 39
+3c = 1 3d = 14 3h = 27 3s = 40
+4c = 2 4d = 15 4h = 28 4s = 41
+5c = 3 5d = 16 5h = 29 5s = 42
+6c = 4 6d = 17 6h = 30 6s = 43
+7c = 5 7d = 18 7h = 31 7s = 44
+8c = 6 8d = 19 8h = 32 8s = 45
+9c = 7 9d = 20 9h = 33 9s = 46
+Tc = 8 Td = 21 Th = 34 Ts = 47
+Jc = 9 Jd = 22 Jh = 35 Js = 48
+Qc = 10 Qd = 23 Qh = 36 Qs = 49
+Kc = 11 Kd = 24 Kh = 37 Ks = 50
+Ac = 12 Ad = 25 Ah = 38 As = 51
+
+*/
Oops, something went wrong.

0 comments on commit 6fa9d57

Please sign in to comment.