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