1 /****************************************************************************
4 Copyright (c) 2001 Jerome Jacovella-St-Louis
7 pokerutils.c - Poker Backend Utilities
8 ****************************************************************************/
13 static int handsRests[10] = { 5, 3, 1, 2, 0, 0, 0, 1, 0, 0 };
15 // { 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, A }
16 // { 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, A }
17 // { 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, A }
18 // { 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, A }
20 // --- Static Utilities ---
22 static int Compare(const int * a, const int * b)
24 if(*a > *b) return 1; else if(*a < *b) return -1; else return 0;
27 static bool POKER_Straight(int cards[5])
31 if((cards[c] / 4 != cards[c-1] / 4 + 1) && !(cards[c - 1] / 4 == 12 && cards[c] / 4 == 0))
36 static bool POKER_Flush(int cards[5])
40 if(cards[c] % 4 != cards[0] % 4)
45 static bool POKER_Same(int cards[5], int howMany, int what[2], int rest[3])
51 for(card = 0; card<13; card++)
54 for(c = 0; c < 5; c++)
56 if(cards[c] / 4 == card)
61 what[numPairs++] = card;
67 qsort(what, numPairs, sizeof(int), Compare);
68 for(d = 0, c = 0; c<5; c++)
71 for(w = 0; w < numPairs; w++)
72 if(cards[c] / 4 == what[w])
81 // --- External Functions ---
83 void POKER_SortCards(int * cards, int numCards)
85 qsort(cards, numCards, sizeof(int), Compare);
88 int POKER_Card(int card)
96 void POKER_ShuffleDeck(int deck[52])
101 count = GetRandom(1000, 2000);
102 for(t = 0; t<count; t++)
107 int indexCut[2] = {0,0};
108 int cut = GetRandom(13, 39);
111 for(c = 0; c<cut; c++)
112 cuts[0][c] = deck[c];
113 for(c = cut; c<52; c++)
114 cuts[1][c - cut] = deck[c];
117 numCut[1] = 52 - cut;
120 for(c = 0; c<52; c++)
124 if(indexCut[0] < numCut[0] && indexCut[1] < numCut[1])
125 whichCut = GetRandom(0,1);
126 else if(indexCut[0] < numCut[0])
128 else if(indexCut[1] < numCut[1])
131 deck[c] = cuts[whichCut][indexCut[whichCut]++];
136 PokerHand POKER_HandType(int cards[5])
138 bool flush, straight;
139 int numPairs, numTris, numQuads;
141 int pairs[2], tris, quads;
143 /*** DETERMINE HAND TYPE ***/
144 flush = POKER_Flush(cards);
145 straight = POKER_Straight(cards);
146 numPairs = POKER_Same(cards, 2, pairs, rest);
147 numTris = POKER_Same(cards, 3, &tris, rest);
148 numQuads = POKER_Same(cards, 4, &quads, rest);
150 if(straight && flush)
152 if(cards[4] / 4 == 12)
155 return straightFlush;
159 else if(numPairs && numTris)
162 return PokerHand::flush;
164 return PokerHand::straight;
167 else if(numPairs == 2)
175 int POKER_Compare(int cards1[5], int cards2[5])
177 bool flush[2], straight[2];
178 int numPairs[2], numTris[2], numQuads[2];
182 int pairs[2][2], tris[2], quads[2];
183 PokerHand handType[2];
192 cards = (h == 0) ? cards1 : cards2;
194 /*** DETERMINE HAND TYPE ***/
195 flush[h] = POKER_Flush(cards);
196 straight[h] = POKER_Straight(cards);
197 numPairs[h] = POKER_Same(cards, 2, pairs[h], rest[h]);
198 numTris[h] = POKER_Same(cards, 3, &tris[h], rest[h]);
199 numQuads[h] = POKER_Same(cards, 4, &quads[h], rest[h]);
201 if(straight[h] && flush[h])
203 if(cards[4] / 4 == 12)
204 handType[h] = royalFlush;
206 handType[h] = straightFlush;
209 handType[h] = fourOfAKind;
210 else if(numPairs[h] && numTris[h])
211 handType[h] = fullHouse;
213 handType[h] = PokerHand::flush;
215 handType[h] = PokerHand::straight;
217 handType[h] = threeOfAKind;
218 else if(numPairs[h] == 2)
219 handType[h] = twoPair;
221 handType[h] = onePair;
224 handType[h] = nothing;
225 CopyBytesBy4(rest[h], cards, 5);
227 numRest[h] = handsRests[handType[h]];
230 /*** DETERMINE WINNING HAND ***/
231 if(handType[1] > handType[0])
233 else if(handType[0] > handType[1])
240 if(cards2[4] / 4 > cards1[4] / 4)
242 else if(cards1[4] / 4> cards2[4] / 4)
246 if(quads[1] > quads[0] )
248 else if(quads[0] > quads[1])
252 if(tris[1] > tris[0] )
254 else if(tris[0] > tris[1])
256 else if(pairs[1][0] > pairs[0][0])
258 else if(pairs[0][0] > pairs[1][0])
261 case PokerHand::flush:
262 for(c = 4; c>=0; c--)
264 if(cards2[c] / 4 > cards1[c] / 4)
269 else if(cards1[c] / 4 > cards2[c] / 4)
276 case PokerHand::straight:
277 if(cards2[4] / 4> cards1[4] / 4)
279 else if(cards1[4] / 4> cards2[4] / 4)
283 if(tris[1] > tris[0] )
285 else if(tris[0] > tris[1])
289 if(pairs[1][1] > pairs[0][1])
291 else if(pairs[0][1] > pairs[1][1])
293 else if(pairs[1][0] > pairs[0][0])
295 else if(pairs[0][0] > pairs[1][0])
299 if(pairs[1][0] > pairs[0][0])
301 else if(pairs[0][0] > pairs[1][0])
306 /*** NO WINNER FROM TYPES, TRY TO SPLIT WITH THE rest ***/
309 for(c = numRest[0] - 1; c>=0; c--)
311 if(rest[1][c] / 4> rest[0][c] / 4)
316 else if(rest[0][c] / 4 > rest[1][c] / 4)
327 void POKER_BestHand(int * cards1, int * cards2, int n1, int n2, int r1, int r2, int output[5])
330 static int start1 = 0;
331 static int start2 = 0;
332 static int currentHand[5];
337 CopyBytesBy4(temp, currentHand, 5);
338 qsort(temp, 5, sizeof(int), Compare);
339 if(POKER_Compare(output, temp) == 1)
340 CopyBytesBy4(output, temp, 5);
349 for(c = start2; c < n2 - (5 - pos - 1); c++)
352 currentHand[pos++] = cards2[c];
353 POKER_BestHand(cards1, cards2, n1, n2, r1, r2, output);
361 for(c = start1; c < n1 - (r1 - pos - 1); c++)
364 currentHand[pos++] = cards1[c];
365 POKER_BestHand(cards1, cards2, n1, n2, r1, r2, output);
371 // Added this recently : was only using 5-r1 from cards2
375 for(c = start1; c < n1 - (5 - pos - 1); c++)
378 currentHand[pos++] = cards1[c];
379 POKER_BestHand(cards1, cards2, n1, n2, r1, r2, output);
387 for(c = start2; c < n2 - (r2 - pos - 1); c++)
390 currentHand[pos++] = cards2[c];
391 POKER_BestHand(cards1, cards2, n1, n2, r1, r2, output);
400 void POKER_BestHand(int * cards, int n, int output[5])
403 static int start = 0;
404 static int currentHand[5];
407 for(c = start; c < n - (5 - pos - 1); c++)
409 currentHand[pos] = cards[c];
413 CopyBytesBy4(temp, currentHand, 5);
414 qsort(temp, 5, sizeof(int), Compare);
415 if(POKER_Compare(output, temp) == 1)
416 CopyBytesBy4(output, temp, 5);
420 int oldStart = start;
423 POKER_BestHand(cards, n, output);