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