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