1 /* 2 * Copyright (C) 2004-2006 3 * Michael Maurer <mjmaurer@yahoo.com> 4 * Brian Goetz <brian@quiotix.com> 5 * Loic Dachary <loic@dachary.org> 6 * 7 * This program gives you software freedom; you can copy, convey, 8 * propagate, redistribute and/or modify this program under the terms of 9 * the GNU General Public License (GPL) as published by the Free Software 10 * Foundation (FSF), either version 3 of the License, or (at your option) 11 * any later version of the GPL published by the FSF. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program in a file in the toplevel directory called "GPLv3". 20 * If not, see <http://www.gnu.org/licenses/>. 21 */ 22 /* 23 Note that this file has two #if .. #endif sections -- one for 24 StdDeck macros to prevent double-inclusion, and one to define the 25 generic Deck_ macros if DECK_STANDARD is defined 26 */ 27 28 #ifndef __DECK_STD_H__ 29 #define __DECK_STD_H__ 30 31 #include "pokereval_export.h" 32 33 /* MUST be lower than STRING_CARDS from lib/deck.c */ 34 #define StdDeck_N_CARDS 52 35 #define StdDeck_MASK(index) (StdDeck_cardMasksTable[index]) 36 37 #define StdDeck_Rank_2 0 38 #define StdDeck_Rank_3 1 39 #define StdDeck_Rank_4 2 40 #define StdDeck_Rank_5 3 41 #define StdDeck_Rank_6 4 42 #define StdDeck_Rank_7 5 43 #define StdDeck_Rank_8 6 44 #define StdDeck_Rank_9 7 45 #define StdDeck_Rank_TEN 8 46 #define StdDeck_Rank_JACK 9 47 #define StdDeck_Rank_QUEEN 10 48 #define StdDeck_Rank_KING 11 49 #define StdDeck_Rank_ACE 12 50 #define StdDeck_Rank_COUNT 13 51 #define StdDeck_Rank_FIRST StdDeck_Rank_2 52 #define StdDeck_Rank_LAST StdDeck_Rank_ACE 53 #define StdDeck_N_RANKMASKS (1 << StdDeck_Rank_COUNT) 54 55 #define StdDeck_RANK(index) ((index) % StdDeck_Rank_COUNT) 56 #define StdDeck_SUIT(index) ((index) / StdDeck_Rank_COUNT) 57 #define StdDeck_MAKE_CARD(rank, suit) ((suit * StdDeck_Rank_COUNT) + rank) 58 59 #define StdDeck_Suit_HEARTS 0 60 #define StdDeck_Suit_DIAMONDS 1 61 #define StdDeck_Suit_CLUBS 2 62 #define StdDeck_Suit_SPADES 3 63 #define StdDeck_Suit_FIRST StdDeck_Suit_HEARTS 64 #define StdDeck_Suit_LAST StdDeck_Suit_SPADES 65 #define StdDeck_Suit_COUNT 4 66 67 typedef uint32 StdDeck_RankMask; 68 69 typedef union { 70 #ifdef USE_INT64 71 uint64 cards_n; 72 #else 73 struct { 74 uint32 n1, n2; 75 } cards_nn; 76 #endif 77 struct { 78 /* There are multiple ways to define these fields. We could pack the 79 13-bit fields together, we could define 13-bit fields with 3-bit 80 padding between them, or we can define them as 16-bit fields. 81 Which is best will depend on the particular characteristics of the 82 processor. 83 If we are on a big-endian processor, the padding should precede the 84 field; on a little-endian processor, the padding should come after 85 the field. 86 I found that uint32 was faster than uint16 on a lot of processors -- 87 the 16-bit instructions can be slow. 88 */ 89 #ifdef WORDS_BIGENDIAN 90 uint32 : 3; 91 uint32 spades :13; 92 uint32 : 3; 93 uint32 clubs :13; 94 uint32 : 3; 95 uint32 diamonds:13; 96 uint32 : 3; 97 uint32 hearts :13; 98 #else 99 uint32 spades :13; 100 uint32 : 3; 101 uint32 clubs :13; 102 uint32 : 3; 103 uint32 diamonds:13; 104 uint32 : 3; 105 uint32 hearts :13; 106 uint32 : 3; 107 #endif 108 } cards; 109 } StdDeck_CardMask; 110 111 #define StdDeck_CardMask_SPADES(cm) ((cm).cards.spades) 112 #define StdDeck_CardMask_CLUBS(cm) ((cm).cards.clubs) 113 #define StdDeck_CardMask_DIAMONDS(cm) ((cm).cards.diamonds) 114 #define StdDeck_CardMask_HEARTS(cm) ((cm).cards.hearts) 115 116 #define StdDeck_CardMask_SET_SPADES(cm, ranks) ((cm).cards.spades=(ranks)) 117 #define StdDeck_CardMask_SET_CLUBS(cm, ranks) ((cm).cards.clubs=(ranks)) 118 #define StdDeck_CardMask_SET_DIAMONDS(cm, ranks) ((cm).cards.diamonds=(ranks)) 119 #define StdDeck_CardMask_SET_HEARTS(cm, ranks) ((cm).cards.hearts=(ranks)) 120 121 #ifdef USE_INT64 122 #define StdDeck_CardMask_OP(result, op1, op2, OP) \ 123 LongLong_OP((result).cards_n, (op1).cards_n, (op2).cards_n, OP); 124 #else 125 #define StdDeck_CardMask_OP(result, op1, op2, OP) \ 126 do { \ 127 (result.cards_nn.n1) = (op1.cards_nn.n1) OP (op2.cards_nn.n1); \ 128 (result.cards_nn.n2) = (op1.cards_nn.n2) OP (op2.cards_nn.n2); \ 129 } while (0) 130 #endif 131 132 #ifdef USE_INT64 133 #define StdDeck_CardMask_NOT(result, op1) \ 134 do { \ 135 (result).cards_n = ~(op1).cards_n; \ 136 } while (0) 137 #else 138 #define StdDeck_CardMask_NOT(result, op1) \ 139 do { \ 140 (result).cards_nn.n1 = ~(op1).cards_nn.n1; \ 141 (result).cards_nn.n2 = ~(op1).cards_nn.n2; \ 142 } while (0) 143 #endif 144 145 #define StdDeck_CardMask_OR(result, op1, op2) \ 146 StdDeck_CardMask_OP(result, op1, op2, |) 147 148 #define StdDeck_CardMask_AND(result, op1, op2) \ 149 StdDeck_CardMask_OP(result, op1, op2, &) 150 151 #define StdDeck_CardMask_XOR(result, op1, op2) \ 152 StdDeck_CardMask_OP(result, op1, op2, ^) 153 154 #define StdDeck_CardMask_SET(mask, index) \ 155 do { \ 156 StdDeck_CardMask _t1 = StdDeck_MASK(index); \ 157 StdDeck_CardMask_OR((mask), (mask), _t1); \ 158 } while (0) 159 160 #define StdDeck_CardMask_UNSET(mask, index) \ 161 do { \ 162 StdDeck_CardMask _t1 = StdDeck_MASK(index); \ 163 StdDeck_CardMask_NOT(_t1, _t1); \ 164 StdDeck_CardMask_AND((mask), (mask), _t1); \ 165 } while (0) 166 167 #ifdef USE_INT64 168 #define StdDeck_CardMask_CARD_IS_SET(mask, index) \ 169 (( (mask).cards_n & (StdDeck_MASK(index).cards_n)) != 0 ) 170 #else 171 /* TODO: this looks wrong; should be ((mask.n1 & i.n1 != 0) || (i.n1 == 0)) */ 172 #define StdDeck_CardMask_CARD_IS_SET(mask, index) \ 173 ((( (mask).cards_nn.n1 & (StdDeck_MASK(index).cards_nn.n1)) != 0 ) \ 174 || (( (mask).cards_nn.n2 & (StdDeck_MASK(index).cards_nn.n2)) != 0 )) 175 #endif 176 177 #ifdef USE_INT64 178 #define StdDeck_CardMask_ANY_SET(mask1, mask2) \ 179 (( (mask1).cards_n & (mask2).cards_n) != 0 ) 180 #else 181 #define StdDeck_CardMask_ANY_SET(mask1, mask2) \ 182 ((( (mask1).cards_nn.n1 & (mask2).cards_nn.n1) != 0 ) \ 183 || (( (mask1).cards_nn.n2 & (mask2).cards_nn.n2) != 0 )) 184 #endif 185 186 #ifdef USE_INT64 187 #define StdDeck_CardMask_RESET(mask) \ 188 do { (mask).cards_n = 0; } while (0) 189 #else 190 #define StdDeck_CardMask_RESET(mask) \ 191 do { (mask).cards_nn.n1 = (mask).cards_nn.n2 = 0; } while (0) 192 #endif 193 194 #ifdef USE_INT64 195 #define StdDeck_CardMask_IS_EMPTY(mask) \ 196 ((mask).cards_n == 0) 197 #else 198 #define StdDeck_CardMask_IS_EMPTY(mask) \ 199 ((mask).cards_nn.n1 == 0 && (mask).cards_nn.n2 == 0) 200 #endif 201 202 #ifdef USE_INT64 203 #define StdDeck_CardMask_EQUAL(mask1, mask2) \ 204 ((mask1).cards_n == (mask2).cards_n) 205 #else 206 #define StdDeck_CardMask_EQUAL(mask1, mask2) \ 207 ((mask1).cards_nn.n1 == (mask2).cards_nn.n1 && (mask1).cards_nn.n2 == (mask2).cards_nn.n2) 208 #endif 209 210 /* 211 #ifdef __cplusplus 212 extern "C" { 213 #endif 214 */ 215 extern POKEREVAL_EXPORT uint8 nBitsTable[StdDeck_N_RANKMASKS]; 216 extern POKEREVAL_EXPORT uint32 topFiveCardsTable[StdDeck_N_RANKMASKS]; 217 extern POKEREVAL_EXPORT uint32 topFiveBitTable[StdDeck_N_RANKMASKS]; 218 extern POKEREVAL_EXPORT uint8 topCardTable[StdDeck_N_RANKMASKS]; 219 extern POKEREVAL_EXPORT uint32 topBitTable[StdDeck_N_RANKMASKS]; 220 extern POKEREVAL_EXPORT uint32 topTwoBitsTable[StdDeck_N_RANKMASKS]; 221 extern POKEREVAL_EXPORT uint32 topFiveBitsTable[StdDeck_N_RANKMASKS]; 222 extern POKEREVAL_EXPORT uint8 straightTable[StdDeck_N_RANKMASKS]; 223 /* 224 #ifdef __cplusplus 225 } 226 #endif 227 */ 228 extern POKEREVAL_EXPORT uint32 bottomFiveCardsTable[StdDeck_N_RANKMASKS]; 229 extern POKEREVAL_EXPORT uint32 bottomFiveJokerTable[StdDeck_N_RANKMASKS]; 230 extern POKEREVAL_EXPORT uint8 bottomCardTable[StdDeck_N_RANKMASKS]; 231 232 extern POKEREVAL_EXPORT StdDeck_CardMask StdDeck_cardMasksTable[StdDeck_N_CARDS]; 233 234 extern POKEREVAL_EXPORT char StdDeck_rankChars[StdDeck_Rank_LAST+1]; 235 extern POKEREVAL_EXPORT char StdDeck_suitChars[StdDeck_Suit_LAST+1]; 236 237 extern POKEREVAL_EXPORT int StdDeck_cardToString(int cardIndex, char *outString); 238 extern POKEREVAL_EXPORT int StdDeck_stringToCard(char *inString, int *outCard); 239 240 #define StdDeck_cardString(i) GenericDeck_cardString(&StdDeck, (i)) 241 #define StdDeck_printCard(i) GenericDeck_printCard(&StdDeck, (i)) 242 #define StdDeck_printMask(m) GenericDeck_printMask(&StdDeck, ((void *) &(m))) 243 #define StdDeck_maskString(m) GenericDeck_maskString(&StdDeck, ((void *) &(m))) 244 #define StdDeck_numCards(m) GenericDeck_numCards(&StdDeck, ((void *) &(m))) 245 #define StdDeck_maskToString(m, s) GenericDeck_maskToString(&StdDeck, ((void *) &(m)), (s)) 246 247 extern POKEREVAL_EXPORT Deck StdDeck; 248 249 250 #endif 251 252 253 254 255 #ifdef DECK_STANDARD 256 257 #if defined(Deck_N_CARDS) 258 #include "deck_undef.h" 259 #endif 260 261 #define Deck_N_CARDS StdDeck_N_CARDS 262 #define Deck_MASK StdDeck_MASK 263 #define Deck_RANK StdDeck_RANK 264 #define Deck_SUIT StdDeck_SUIT 265 266 #define Rank_2 StdDeck_Rank_2 267 #define Rank_3 StdDeck_Rank_3 268 #define Rank_4 StdDeck_Rank_4 269 #define Rank_5 StdDeck_Rank_5 270 #define Rank_6 StdDeck_Rank_6 271 #define Rank_7 StdDeck_Rank_7 272 #define Rank_8 StdDeck_Rank_8 273 #define Rank_9 StdDeck_Rank_9 274 #define Rank_TEN StdDeck_Rank_TEN 275 #define Rank_JACK StdDeck_Rank_JACK 276 #define Rank_QUEEN StdDeck_Rank_QUEEN 277 #define Rank_KING StdDeck_Rank_KING 278 #define Rank_ACE StdDeck_Rank_ACE 279 #define Rank_FIRST StdDeck_Rank_FIRST 280 #define Rank_COUNT StdDeck_Rank_COUNT 281 282 #define Suit_HEARTS StdDeck_Suit_HEARTS 283 #define Suit_DIAMONDS StdDeck_Suit_DIAMONDS 284 #define Suit_CLUBS StdDeck_Suit_CLUBS 285 #define Suit_SPADES StdDeck_Suit_SPADES 286 #define Suit_FIRST StdDeck_Suit_FIRST 287 #define Suit_COUNT StdDeck_Suit_COUNT 288 289 #define CardMask StdDeck_CardMask 290 #define CardMask_NOT StdDeck_CardMask_NOT 291 #define CardMask_OR StdDeck_CardMask_OR 292 #define CardMask_XOR StdDeck_CardMask_XOR 293 #define CardMask_AND StdDeck_CardMask_AND 294 #define CardMask_SET StdDeck_CardMask_SET 295 #define CardMask_CARD_IS_SET StdDeck_CardMask_CARD_IS_SET 296 #define CardMask_ANY_SET StdDeck_CardMask_ANY_SET 297 #define CardMask_RESET StdDeck_CardMask_RESET 298 #define CardMask_UNSET StdDeck_CardMask_UNSET 299 300 #define CardMask_SPADES StdDeck_CardMask_SPADES 301 #define CardMask_HEARTS StdDeck_CardMask_HEARTS 302 #define CardMask_CLUBS StdDeck_CardMask_CLUBS 303 #define CardMask_DIAMONDS StdDeck_CardMask_DIAMONDS 304 305 #define CardMask_SET_SPADES StdDeck_CardMask_SET_SPADES 306 #define CardMask_SET_HEARTS StdDeck_CardMask_SET_HEARTS 307 #define CardMask_SET_CLUBS StdDeck_CardMask_SET_CLUBS 308 #define CardMask_SET_DIAMONDS StdDeck_CardMask_SET_DIAMONDS 309 310 #define CurDeck StdDeck 311 312 #endif 313