/usr/include/poker-eval/enumord.h is in libpoker-eval-dev 138.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | /*
* Copyright (C) 2004-2006
* Michael Maurer <mjmaurer@yahoo.com>
* Loic Dachary <loic@dachary.org>
*
* This program gives you software freedom; you can copy, convey,
* propagate, redistribute and/or modify this program under the terms of
* the GNU General Public License (GPL) as published by the Free Software
* Foundation (FSF), either version 3 of the License, or (at your option)
* any later version of the GPL published by the FSF.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program in a file in the toplevel directory called "GPLv3".
* If not, see <http://www.gnu.org/licenses/>.
*/
/* $Id: enumord.h 5146 2008-12-04 03:11:22Z bkuhn $ */
/*
Definitions for computing a histogram of final hand orderings.
A final hand ordering is defined by the relative rank of each player's hand
after all cards are dealt. For example, in a high-only game with 3 players,
the possible final hand orderings for players A, B, and C are (where
comma denotes tie):
A B C
A C B
B A C
B C A
C A B
C B A
A B,C
B A,C
C A,B
A,B C
A,C B
B,C A
A,B,C
Another way to reprsent this is to assign a player to a column and write
the relative hand rank (1=best) in that column. Then the possibilities
above are written (in the same order as above) as
A B C
-----
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
1 2 2
2 1 2
2 2 1
1 1 2
1 2 1
2 1 1
1 1 1
Our encoding here is based on the second form.
For high/low games, we track the full combination of outcomes. In a
2-person game with a qualifier for low, the possible outcomes are:
HI LO
A B A B
1 1 1 1 tie for high; tie for low
1 1 1 2 tie for high; A wins low
1 1 1 NQ tie for high; A wins low, B doesn't qualify low
1 1 2 1 tie for high; B wins low
1 1 NQ 1 etc.
1 1 NQ NQ
1 2 1 1
1 2 1 2
1 2 1 NQ
1 2 2 1
1 2 NQ 1
1 2 NQ NQ
2 1 1 1
2 1 1 2
2 1 1 NQ
2 1 2 1
2 1 NQ 1
2 1 NQ NQ
For ease of programming, we are somewhat wasteful of memory when storing the
histogram of outcomes. We allocate an array such that hist[i] is the number
of times that outcome i occurs. The integer i encodes the ordering of N
players' hand ranks by using N bit fields, each bit field just large enough
to represent the numbers [0..N]. The value 0 in bit field K indicates that
player K has the strongest hand (possibly tying another player); the value
N-1 indicates player K has the weakest hand; the value N indicates a
non-qualifying hand (such as a 9-low in 8-or-better). Note that not all
integers i correspond to valid rank orderings, both due the fact that for
some values of N the bit field can encode values greater than N, and due to
the fact that some rank orderings, like a 3-way tie for 3rd place, are
impossible. That is the wasteful part; a hash table would solve it.
For high-low games, we use two such sets of bit fields, packed adjacent to
one another in a single integer. The high-order bit fields correspond to
the high hand; the low-order bit fields correspond to the low hand.
Michael Maurer, Jun 2002
*/
#ifndef ENUMORD_H
#define ENUMORD_H
#include "pokereval_export.h"
#include "poker_defs.h"
/* largest integer N such that N * ENUM_ORDERING_NBITS(N) < 32 */
#define ENUM_ORDERING_MAXPLAYERS 7
/* largest integer N such that 2 * N * ENUM_ORDERING_NBITS(N) < 32 */
#define ENUM_ORDERING_MAXPLAYERS_HILO 5
typedef enum {
enum_ordering_mode_none = 0,
enum_ordering_mode_hi,
enum_ordering_mode_lo,
enum_ordering_mode_hilo
} enum_ordering_mode_t;
typedef struct {
enum_ordering_mode_t mode;
unsigned int nplayers;
unsigned int nentries; /* equal to ENUM_ORDERING_NENTRIES(nplayers)
or ENUM_ORDERING_NENTRIES_HILO(nplayers),
depending on mode */
/* hist[i] is the number of outcomes in which the ordering of players'
relative hand values corresponds to ordering i. We encode each ordering
as an integer i such that ENUM_ORDERING_DECODE_PLAYER_K(i, n, k) gives
the relative hand rank of player k out of n players. Rank is encoded as
an integer in [0,n] where 0=strongest, n-1=weakest, n=non-qualifying. */
unsigned int *hist; /* has nenetries elements */
} enum_ordering_t;
extern POKEREVAL_EXPORT int enum_nbits[ENUM_ORDERING_MAXPLAYERS+1];
extern POKEREVAL_EXPORT void enum_ordering_rank(HandVal *hands, int noqual,
int nplayers, int *ranks, int reverse);
/* the bit field size for one player's relative hand rank */
#define ENUM_ORDERING_NBITS(nplayers) \
((nplayers < 0 || nplayers >= sizeof(enum_nbits)/sizeof(enum_nbits[0])) \
? -1 : enum_nbits[nplayers])
/* the number of elements in the hist[] array */
#define ENUM_ORDERING_NENTRIES(nplayers) \
(((nplayers > ENUM_ORDERING_MAXPLAYERS) || \
ENUM_ORDERING_NBITS(nplayers) < 0) \
? -1 : (1 << (nplayers * ENUM_ORDERING_NBITS(nplayers))))
/* the number of elements in the hist[] array in high/low games */
#define ENUM_ORDERING_NENTRIES_HILO(nplayers) \
(((nplayers > ENUM_ORDERING_MAXPLAYERS_HILO) || \
ENUM_ORDERING_NBITS(nplayers) < 0) \
? -1 : (1 << (2 * nplayers * ENUM_ORDERING_NBITS(nplayers))))
/* Compute the integer encoding of a given array of relative hand rankings.
ranks[k] is relative hand rank of player k's hand; rank=0 is best,
rank=nplayers-1 is worst, rank=nplayers is non-qualifying. Caller must
ensure that 0 <= ranks[k] <= nplayers. */
#define ENUM_ORDERING_ENCODE(encoding, nplayers, ranks) \
do { \
int _k; \
int _nbits = ENUM_ORDERING_NBITS(nplayers); \
(encoding) = 0; \
for (_k=0; _k<(nplayers); _k++) \
(encoding) = ((encoding) << _nbits) | ((ranks)[_k]); \
} while (0)
/* Compute the integer encoding of a given array of relative hand rankings
for high/low games. */
#define ENUM_ORDERING_ENCODE_HILO(encoding, nplayers, hiranks, loranks) \
do { \
int _k; \
int _nbits = ENUM_ORDERING_NBITS(nplayers); \
(encoding) = 0; \
for (_k=0; _k<(nplayers); _k++) \
(encoding) = ((encoding) << _nbits) | ((hiranks)[_k]); \
for (_k=0; _k<(nplayers); _k++) \
(encoding) = ((encoding) << _nbits) | ((loranks)[_k]); \
} while (0)
/* the number of bits to the start of the bit field for player k */
#define ENUM_ORDERING_SHIFT_K(nplayers, k) \
(((nplayers) - (k) - 1) * ENUM_ORDERING_NBITS(nplayers))
/* the number of bits to the start of the bit field for player k's high
hand, in a high/low game */
#define ENUM_ORDERING_SHIFT_HILO_K_HI(nplayers, k) \
((2*(nplayers) - (k) - 1) * ENUM_ORDERING_NBITS(nplayers))
/* the number of bits to the start of the bit field for player k's low
hand, in a high/low game */
#define ENUM_ORDERING_SHIFT_HILO_K_LO(nplayers, k) \
(((nplayers) - (k) - 1) * ENUM_ORDERING_NBITS(nplayers))
/* a bit mask covering the bit field for player k */
#define ENUM_ORDERING_MASK_K(nplayers, k) \
((~(~0 << ENUM_ORDERING_NBITS(nplayers))) << \
ENUM_ORDERING_SHIFT_K((nplayers), (k)))
/* a bit mask covering the bit field for player k's high hand, in a high/low
game */
#define ENUM_ORDERING_MASK_HILO_K_HI(nplayers, k) \
((~(~0 << ENUM_ORDERING_NBITS(nplayers))) << \
ENUM_ORDERING_SHIFT_HILO_K_HI((nplayers), (k)))
/* a bit mask covering the bit field for player k's low hand, in a high/low
game */
#define ENUM_ORDERING_MASK_HILO_K_LO(nplayers, k) \
((~(~0 << ENUM_ORDERING_NBITS(nplayers))) << \
ENUM_ORDERING_SHIFT_HILO_K_LO((nplayers), (k)))
/* decodes the integer encoding to yield the relative rank of
player k's hand */
#define ENUM_ORDERING_DECODE_K(encoding, nplayers, k) \
(((encoding) & ENUM_ORDERING_MASK_K((nplayers), (k))) >> \
ENUM_ORDERING_SHIFT_K((nplayers), (k)))
/* decodes the integer encoding to yield the relative rank of
player k's high hand in a high/low game */
#define ENUM_ORDERING_DECODE_HILO_K_HI(encoding, nplayers, k) \
(((encoding) & ENUM_ORDERING_MASK_HILO_K_HI((nplayers), (k))) >> \
ENUM_ORDERING_SHIFT_HILO_K_HI((nplayers), (k)))
/* decodes the integer encoding to yield the relative rank of
player k's low hand in a high/low game */
#define ENUM_ORDERING_DECODE_HILO_K_LO(encoding, nplayers, k) \
(((encoding) & ENUM_ORDERING_MASK_HILO_K_LO((nplayers), (k))) >> \
ENUM_ORDERING_SHIFT_HILO_K_LO((nplayers), (k)))
/* given hands[], assigns ranks[k] such that a rank of 0 indicates that
hands[k] is the highest hand value in hands[], a rank of 1 indicates
that hands[k] is the next highest value, etc., and a rank of nplayers
indicates that hands[k] is equal to noqual (the not-qualifying hand) */
#define ENUM_ORDERING_RANK_HI(hands, noqual, nplayers, ranks) \
enum_ordering_rank((hands), (noqual), (nplayers), (ranks), 0)
/* given hands[], assigns ranks[k] such that a rank of 0 indicates that
hands[k] is the lowest hand value in hands[], a rank of 1 indicates
that hands[k] is the next lowest value, etc., and a rank of nplayers
indicates that hands[k] is equal to noqual (the not-qualifying hand) */
#define ENUM_ORDERING_RANK_LO(hands, noqual, nplayers, ranks) \
enum_ordering_rank((hands), (noqual), (nplayers), (ranks), 1)
/* increments the histogram bin value corresponding to the ranks[] array */
#define ENUM_ORDERING_INCREMENT(ordering, nplayers, ranks) \
do { \
int _encoding; \
ENUM_ORDERING_ENCODE(_encoding, (nplayers), (ranks)); \
(ordering)->hist[_encoding]++; \
} while (0)
/* increments the histogram bin value corresponding to the ranks[] array,
for high/low games*/
#define ENUM_ORDERING_INCREMENT_HILO(ordering, nplayers, hiranks, loranks) \
do { \
int _encoding; \
ENUM_ORDERING_ENCODE_HILO(_encoding, (nplayers), (hiranks), (loranks)); \
(ordering)->hist[_encoding]++; \
} while (0)
#endif
|