2 This code is produced by mykey1961 and ported to C by pokercurious from the pokerai.org forums.
4 This evaluator has two advantages over the one in pokereval.cpp, making pokereval.cpp
5 obsolete if it didn't include the 5-hand evaluator: it doesn't require a 124MB file on disk,
6 and, it's 3 times faster.
8 Cleaned up a bit, used int64_t, made work with g++ compiler,
9 and placed two .c files in one .cpp file for OOPoker. Made interface
10 around it that uses one integer per card.
12 Applied bugfix mentioned in http://poker-ai.org/archive/pokerai.org/pf3/viewtopica3e8-2.html
15 #include "pokereval2.h"
23 #define HIGH_FLAG 0x100000
24 #define PAIR_FLAG 0x200000
25 #define TWOPAIR_FLAG 0x300000
26 #define TRIP_FLAG 0x400000
27 #define STRAIGHT_FLAG 0x500000
28 #define FLUSH_FLAG 0x600000
29 #define HOUSE_FLAG 0x700000
30 #define QUAD_FLAG 0x800000
31 #define STRFLUSH_FLAG 0x900000
33 unsigned int Flush
[8129];
34 unsigned int Straight
[8129];
35 unsigned int Top1_16
[8129];
36 unsigned int Top1_12
[8129];
37 unsigned int Top1_8
[8129];
38 unsigned int Top2_12
[8129];
39 unsigned int Top2_8
[8129];
40 unsigned int Top3_4
[8129];
41 unsigned int Top5
[8129];
42 unsigned int Bit1
[8129];
43 unsigned int Bit2
[8129];
45 HandMask HandMasksTable
[52] =
47 0x0001000000000000ULL
,
48 0x0002000000000000ULL
,
49 0x0004000000000000ULL
,
50 0x0008000000000000ULL
,
51 0x0010000000000000ULL
,
52 0x0020000000000000ULL
,
53 0x0040000000000000ULL
,
54 0x0080000000000000ULL
,
55 0x0100000000000000ULL
,
56 0x0200000000000000ULL
,
57 0x0400000000000000ULL
,
58 0x0800000000000000ULL
,
59 0x1000000000000000ULL
,
60 0x0000000100000000ULL
,
61 0x0000000200000000ULL
,
62 0x0000000400000000ULL
,
63 0x0000000800000000ULL
,
64 0x0000001000000000ULL
,
65 0x0000002000000000ULL
,
66 0x0000004000000000ULL
,
67 0x0000008000000000ULL
,
68 0x0000010000000000ULL
,
69 0x0000020000000000ULL
,
70 0x0000040000000000ULL
,
71 0x0000080000000000ULL
,
72 0x0000100000000000ULL
,
73 0x0000000000010000ULL
,
74 0x0000000000020000ULL
,
75 0x0000000000040000ULL
,
76 0x0000000000080000ULL
,
77 0x0000000000100000ULL
,
78 0x0000000000200000ULL
,
79 0x0000000000400000ULL
,
80 0x0000000000800000ULL
,
81 0x0000000001000000ULL
,
82 0x0000000002000000ULL
,
83 0x0000000004000000ULL
,
84 0x0000000008000000ULL
,
85 0x0000000010000000ULL
,
86 0x0000000000000001ULL
,
87 0x0000000000000002ULL
,
88 0x0000000000000004ULL
,
89 0x0000000000000008ULL
,
90 0x0000000000000010ULL
,
91 0x0000000000000020ULL
,
92 0x0000000000000040ULL
,
93 0x0000000000000080ULL
,
94 0x0000000000000100ULL
,
95 0x0000000000000200ULL
,
96 0x0000000000000400ULL
,
97 0x0000000000000800ULL
,
102 HandVal
RankHand(HandMask hand
)
104 unsigned int c
, h
, d
, s
;
105 unsigned int p1
, p2
, p3
, p4
;
108 h
= (hand
>> 16) & 0x1fff;
109 d
= (hand
>> 32) & 0x1fff;
110 c
= (hand
>> 48) & 0x1fff;
112 if (Flush
[s
] | Flush
[h
] | Flush
[d
] | Flush
[c
])
113 return Flush
[s
] | Flush
[h
] | Flush
[d
] | Flush
[c
];
116 p2
= p1
& h
; p1
= p1
| h
;
117 p3
= p2
& d
; p2
= p2
| (p1
& d
); p1
= p1
| d
;
118 p4
= p3
& c
; p3
= p3
| (p2
& c
); p2
= p2
| (p1
& c
); p1
= p1
| c
;
123 if (!p2
) // There are no pairs
124 return HIGH_FLAG
| Top5
[p1
];
126 if (!p3
) // There are pairs but no triplets
129 return PAIR_FLAG
| Top1_16
[p2
] | Top3_4
[p1
^ Bit1
[p2
]];
130 return TWOPAIR_FLAG
| Top2_12
[p2
] | Top1_8
[p1
^ Bit2
[p2
]];
133 if (!p4
) // Deal with trips/sets/boats
135 if ((p2
> p3
) || (p3
& (p3
-1)))
136 return HOUSE_FLAG
| Top1_16
[p3
] | Top1_12
[p2
^ Bit1
[p3
]];
137 return TRIP_FLAG
| Top1_16
[p3
] | Top2_8
[p1
^ Bit1
[p3
]];
140 // Only hands left are quads
141 return QUAD_FLAG
| Top1_16
[p4
] | Top1_12
[p1
^ p4
];
146 void InitializeHandRankingTables(void)
148 unsigned int i
, c1
, c2
, c3
, c4
, c5
, c6
, c7
;
150 for (i
= 0; i
<= 0x1fc0; i
++)
165 for (c1
= 14; c1
> 4; c1
--) {
170 if (c5
== 1) c5
= 14;
171 for (c6
= 14; c6
> 1; c6
--) {
173 for (c7
= c6
-1; c7
> 1; c7
--) {
175 i
= (1 << c1
) | (1 << c2
) | (1 << c3
) | (1 << c4
) | (1 << c5
) | (1 << c6
) | (1 << c7
);
176 Flush
[i
>> 2] = STRFLUSH_FLAG
| (c1
<< 16) | (c2
<< 12) | (c3
<< 8) | (c4
<< 4) | c5
;
177 Straight
[i
>> 2] = STRAIGHT_FLAG
| (c1
<< 16) | (c2
<< 12) | (c3
<< 8) | (c4
<< 4) | c5
;
184 for (c1
= 14; c1
> 5; c1
--) {
185 for (c2
= c1
-1; c2
> 4; c2
--) {
186 for (c3
= c2
-1; c3
> 3; c3
--) {
187 for (c4
= c3
-1; c4
> 2; c4
--) {
188 for (c5
= c4
-1; c5
> 1; c5
--) {
189 for (c6
= c5
; c6
> 1; c6
--) {
190 for (c7
= c6
; c7
> 1; c7
--) {
191 i
= (1 << c1
) | (1 << c2
) | (1 << c3
) | (1 << c4
) | (1 << c5
) | (1 << c6
) | (1 << c7
);
192 if (Flush
[i
>> 2] == 0)
193 Flush
[i
>> 2] = FLUSH_FLAG
| (c1
<< 16) | (c2
<< 12) | (c3
<< 8) | (c4
<< 4) | c5
;
194 Top5
[i
>> 2] = HIGH_FLAG
| (c1
<< 16) | (c2
<< 12) | (c3
<< 8) | (c4
<< 4) | c5
;
203 for (c1
= 14; c1
> 3; c1
--) {
204 for (c2
= c1
-1; c2
> 2; c2
--) {
205 for (c3
= c2
-1; c3
> 1; c3
--) {
206 for (c4
= c3
; c4
> 1; c4
--) {
207 for (c5
= c4
; c5
> 1; c5
--) {
208 for (c6
= c5
; c6
> 1; c6
--) {
209 for (c7
= c6
; c7
> 1; c7
--) {
210 i
= (1 << c1
) | (1 << c2
) | (1 << c3
) | (1 << c4
) | (1 << c5
) | (1 << c6
) | (1 << c7
);
211 Top3_4
[i
>> 2] = (c1
<< 12) | (c2
<< 8) | (c3
<< 4);
220 for (c1
= 14; c1
> 2; c1
--) {
221 for (c2
= c1
-1; c2
> 1; c2
--) {
222 for (c3
= c2
; c3
> 1; c3
--) {
223 for (c4
= c3
; c4
> 1; c4
--) {
224 for (c5
= c4
; c5
> 1; c5
--) {
225 for (c6
= c5
; c6
> 1; c6
--) {
226 for (c7
= c6
; c7
> 1; c7
--) {
227 i
= (1 << c1
) | (1 << c2
) | (1 << c3
) | (1 << c4
) | (1 << c5
) | (1 << c6
) | (1 << c7
);
228 Top2_12
[i
>> 2] = (c1
<< 16) | (c2
<< 12);
229 Top2_8
[i
>> 2] = (c1
<< 12) | (c2
<< 8);
230 Bit2
[i
>> 2] = (1 << (c1
-2)) | (1 << (c2
-2));
239 for (c1
= 14; c1
> 1; c1
--) {
240 for (c2
= c1
; c2
> 1; c2
--) {
241 for (c3
= c2
; c3
> 1; c3
--) {
242 for (c4
= c3
; c4
> 1; c4
--) {
243 for (c5
= c4
; c5
> 1; c5
--) {
244 for (c6
= c5
; c6
> 1; c6
--) {
245 for (c7
= c6
; c7
> 1; c7
--) {
246 i
= (1 << c1
) | (1 << c2
) | (1 << c3
) | (1 << c4
) | (1 << c5
) | (1 << c6
) | (1 << c7
);
247 Top1_16
[i
>> 2] = (c1
<< 16);
248 Top1_12
[i
>> 2] = (c1
<< 12);
249 Top1_8
[i
>> 2] = (c1
<< 8);
250 Bit1
[i
>> 2] = (1 << (c1
-2));