/home/toolbox/public_html/solutions/103/10315/e.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <fcntl.h>
6 #include <stdint.h>
7 #include <math.h>
8 #include <stdlib.h>
9
10 #define TRUE (1 == 1)
11 #define FALSE (1 != 1)
12
13 #define DEBUG if (FALSE)
14
15 #define NCARDS 52
16 #define NSUITS 4
17
18 typedef struct
19 {
20 int hand[5]; /* holds number of each card in players hand */
21 int suits[4]; /* has count of how of each suit in players hand */
22 int values[13]; /* has count of how many of each value in players hand */
23 int cardHash; /* 6 hex digit number, first digit is how hand evaluates,
24 next 5 digits are the value of each card */
25 int pairs; /* how many pairs are in hand */
26 int triple; /* how many 3 of a kinds in hand */
27 int quad; /* how many 4 of a kinds in hand */
28 int flush; /* 0 if not flush, 1 is a flush - how many flushes in hand */
29 int straight; /* 0 if not straight, 1 if straight */
30 } evalStruct;
31
32 /****************************************************************
33 Table of possibilities:
34 pairs | triple | quad | flush | straight ||
35 +------+--------+------+-------+----------++
36 Straight Flush | 0 | 0 | 0 | 1 | 1 || 3
37 Four of a Kind | 0 | 0 | 1 | 0 | 0 || 4
38 Full House | 1 | 1 | 0 | 0 | 0 || 24
39 Flush | 0 | 0 | 0 | 1 | 0 || 2
40 Straight | 0 | 0 | 0 | 0 | 1 || 1
41 Three of a Kind | 0 | 1 | 0 | 0 | 0 || 8
42 Two Pair | 2 | 0 | 0 | 0 | 0 || 32
43 One Pair | 1 | 0 | 0 | 0 | 0 || 16
44 High Card | 0 | 0 | 0 | 0 | 0 || 0
45
46 At this point, we have a state table describing every possible outcome. The array
47 result implements this state table.
48 ****************************************************************/
49
50 char cards[] = "23456789TJQKA";
51 char suits[] = "CDHS";
52 int result[35];
53
54 evalStruct white;
55 evalStruct black;
56
57 /*
58 * Author: Isaac Traxler, Josh Abadie
59 * Date: 20080324
60 * Purpose:
61 * Problem: 10315
62 */
63
64 void init()
65 {
66 /* FUNCTION init */ /* initialize state table */
67 result[3] = 9; /* straight flush */
68 result[4] = 8; /* four of a kind */
69 result[24] = 7; /* full house */
70 result[2] = 6; /* flush */
71 result[1] = 5; /*straight */
72 result[8] = 4; /* three of a kind */
73 result[32] = 3; /* two pair */
74 result[16] = 2; /* pair */
75 result[0] = 1; /* high card */
76 } /* FUNCTION init */
77
78 int rankCard(char value, char suit)
79 {
80 /* FUNCTION rankCard */
81 /* adapted from Programming Challenges */
82 /* This routine will take the value (2-A) and the suit and from that determine
83 the card's number (2C - 0, 2D - 1, 2H - 2, 2S - 3, 3C -4 ... AH - 50, AS - 51)
84 */
85 int k; /* counters */
86 int i = -1;
87 int j = -1;
88
89 for (k=0; (strlen(cards)>k) && (-1 == i); k++)
90 {
91 /* for */
92 if (value == cards[k])
93 {
94 i = k;
95 }
96 } /* for */
97 for (k=0; (strlen(suits)>k) && (-1 == j); k++)
98 {
99 /* for */
100 if (suit == suits[k])
101 {
102 j = k;
103 }
104 } /* for */
105 DEBUG printf("%c %c - %d %d %d\n",value, suit, i, j, i * NSUITS + j);
106 return (i * NSUITS + j);
107 } /* FUNCTION rankCard */
108
109 int suitIndex(int card)
110 {
111 /* FUNCTION suit */
112 /* adapted from Programming Challenges */
113 return (card % NSUITS);
114 } /* FUNCTION suit */
115
116 int cardIndex(int crd)
117 {
118 /* FUNCTION card */
119 /* adapted from Programming Challenges */
120 return (crd/NSUITS);
121 } /* FUNCTION card */
122
123 void initStruct(evalStruct *p)
124 {
125 /* FUNCTION initStruct */
126 int i;
127
128 for (i=0; 4>i; i++)
129 {
130 /* for */
131 p->suits[i] = 0;
132 p->values[i] = 0;
133 } /* for */
134 for (i=4; 13>i; i++)
135 {
136 /* for */
137 p->values[i] = 0;
138 } /* for */
139 } /* FUNCTION initStruct */
140
141 void dump(evalStruct p, char * color)
142 {
143 /* FUNCTION dump */
144 int i;
145
146 printf("%s:\n", color);
147 printf("\tpairs:%d\n", p.pairs);
148 printf("\ttriple:%d\n", p.triple);
149 printf("\tquad:%d\n", p.quad);
150 printf("\tstraight:%d\n", p.straight);
151 printf("\tflush:%d\n", p.flush);
152 printf("\tHand:");
153 for (i = 0; i < 5; i ++)
154 {
155 printf("\t%d", p.hand[i]);
156 }
157 printf("\n");
158 printf("\tSuits:");
159 for (i = 0; i < 4; i ++)
160 {
161 printf("\t%d", p.suits[i]);
162 }
163 printf("\n");
164 printf("\tCounts:");
165 for (i = 0; i < 13; i ++)
166 {
167 printf("\t%d", p.values[i]);
168 }
169 printf("\n");
170 printf("\tcardHash:\t%d %x\n", p.cardHash, p.cardHash);
171 } /* FUNCTION dump */
172
173 int getInput()
174 {
175 /* FUNCTION getInput */
176 int dataReadFlag = TRUE;
177 char buffer[5];
178 int i;
179
180 if (EOF == scanf(" %s ", buffer))
181 {
182 /* at EOF */
183 dataReadFlag = FALSE;
184 } /* at EOF */
185 else
186 {
187 /* reading in the rest */
188 black.hand[0] = rankCard(buffer[0], buffer[1]);
189 for (i = 1; i < 5; i ++)
190 {
191 /* input loop */
192 scanf(" %s ", buffer);
193 black.hand[i] = rankCard(buffer[0], buffer[1]);
194 } /* input loop */
195 for (i = 0; i < 5; i ++)
196 {
197 /* input loop */
198 scanf(" %s ", buffer);
199 white.hand[i] = rankCard(buffer[0], buffer[1]);
200 } /* input loop */
201
202 } /* reading in the rest */
203
204 return (dataReadFlag);
205 } /* FUNCTION getInput */
206
207
208 int detTest(int * ary, int count)
209 {
210 /* FUNCTION detTest */
211 int i;
212 int toReturn = 0;
213
214 for (i = 0; 13 > i; i ++)
215 {
216 /* for loop */
217 if (ary[i] == count)
218 {
219 /* found a match */
220 toReturn++;
221 } /* found a match */
222 } /* for loop */
223 return toReturn;
224 } /* FUNCTION detTest */
225
226 int detFlush(int * ary)
227 {
228 /* FUNCTION detFlush */
229 int i;
230 int toReturn = 0;
231
232 for ( i = 0; 4 > i; i ++)
233 {
234 /* for */
235 if (5 == ary[i])
236 {
237 /* flush found */
238 toReturn = 1;
239 } /* flush found */
240 } /* for */
241 return toReturn;
242 } /* FUNCTION detFlush */
243
244
245 int detStraight(int * ary)
246 {
247 /* FUNCTION detStraight */
248 int i;
249 int toReturn = 0;
250 int tot = 0;
251
252 /* convert array into an integer */
253 tot = 0;
254 for (i=0; 13>i; i++)
255 {
256 /* for */
257 tot = tot * 2 + ary[i];
258 } /* for */
259
260 /* compare integer to all 13-bit numbers that have exactly 5 consecutive
261 bits set */
262 if ((31 == tot) || (62 == tot) || (124 == tot) ||
263 (248 == tot) || (496 == tot) || (992 == tot) ||
264 (1984 == tot) || (3968 == tot) || (7936 == tot))
265 {
266 /* found a straight */
267 toReturn = 1;
268 } /* found a straight */
269
270 return toReturn;
271 } /* FUNCTION detStraight */
272
273 int calcHash(evalStruct eval)
274 {
275 /* FUNCTION calcHash */
276 int i,j,k;
277 int toReturn;
278
279 toReturn = eval.cardHash; /* start wih kind of hand and then append each card */
280 for (j = 4; 0 < j; j --)
281 {
282 /* for number of matching cards */
283 for (i = 12; -1 < i; i --)
284 {
285 /* values */
286 if (eval.values[i] == j)
287 {
288 /* add to array */
289 for (k = 0; k < j; k ++)
290 {
291 /* handle each card */
292 toReturn = toReturn *16 + i;
293 } /* handle each card */
294 } /* add to array */
295 } /* values */
296 } /* for number of matching cards */
297 return toReturn;
298 } /* FUNCTION calcHash */
299
300 void evaluateHand(evalStruct *eval)
301 {
302 /* FUNCTION evaluateHand */
303 int i;
304
305 for (i=0; 5>i; i++)
306 {
307 /* for */
308 eval->suits[suitIndex(eval->hand[i])]++;
309 eval->values[cardIndex(eval->hand[i])]++;
310 } /* for */
311 /* determine number of pairs */
312 eval->pairs = detTest(eval->values, 2);
313 /* determine 3 of a kind */
314 eval->triple = detTest(eval->values, 3);
315 /* determine 4 of a kind */
316 eval->quad = detTest(eval->values, 4);
317 /* determine flush */
318 eval->flush = detFlush(eval->suits);
319 /* determine straight */
320 eval->straight = detStraight(eval->values);
321 eval->cardHash = result[(eval->pairs * 16) + (eval->triple * 8) +
322 (eval->quad * 4) + (eval->flush * 2) +
323 (eval->straight)];
324 eval->cardHash = calcHash(*eval);
325 } /* FUNCTION evaluateHand */
326
327 void process()
328 {
329 /* FUNCTION process */
330 initStruct(&black);
331 initStruct(&white);
332 evaluateHand(&black);
333 evaluateHand(&white);
334 if (white.cardHash > black.cardHash)
335 {
336 /* white wins */
337 printf("White wins.\n");
338 } /* white wins */
339 else if (black.cardHash > white.cardHash)
340 {
341 /* black wins */
342 printf("Black wins.\n");
343 } /* black wins */
344 else
345 {
346 /* tie for hands */
347 printf("Tie.\n");
348 } /* tie for hands */
349
350 DEBUG dump(black, "Black");
351 DEBUG dump(white, "White");
352 } /* FUNCTION process */
353
354 int main ()
355 {
356 /* main */
357 int moreToDo;
358
359 init();
360 moreToDo = getInput();
361 while (moreToDo)
362 {
363 /* while */
364 process();
365 moreToDo = getInput();
366 } /* while */
367
368 return EXIT_SUCCESS;
369 } /* main */
370