1 /*
2 * (c) Copyright 1997, Qun Zhang.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without fee,
6 * provided that the above copyright notice appear in all copies and
7 * that both that copyright notice and this permission notice appear in
8 * supporting documentation, and that the name of Qun Zhang not be used
9 * in advertising or publicity pertaining to distribution of the software
10 * without specific, written prior permission. Qun Zhang make no
11 * representations about the suitability of this software for any purpose.
12 * It is provided "as is" without express or implied warranty.
13 *
14 * THE ABOVE-NAMED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE ABOVE-NAMED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
18 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
19 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 */
23
24 #include "Card.h"
25 #include "Hands.h"
26
27
28 const int Hands::Ratio[11] = {0, 1, 1, 2, 3, 4, 5, 7, 20, 50, 100 };
29 const char * Hands::HandNames[11] = { " ",
30 " ",
31 " One Pair ",
32 " Two Pairs",
33 " 3 of a Kind",
34 " Straight ",
35 " Flush ",
36 " Full House",
37 " 4 of a Kind",
38 " Straight Flush ",
39 " Royal Flush " };
40
41
Hands()42 Hands::Hands() : _score(0), _hand(EX)
43 {
44 for(int i=0; i < 5; i++)
45 _cards[i] = ( Card *)0;
46 _next = 0;
47 }
48
HandValue() const49 enum Hands::Hand Hands::HandValue() const
50 {
51 return _hand;
52 }
53
NumOfCards() const54 int Hands::NumOfCards() const
55 {
56 return (_cards[0] == (Card*) 0) ? 0 : 5;
57 }
58
Score() const59 long Hands::Score() const
60 {
61 if(_score == 0)
62 SortCards();
63 #ifdef DEBUG
64 cout << "Score: " << _score <<endl;
65 #endif
66 return _score;
67 }
68
HandName() const69 const char* const Hands::HandName() const
70 {
71 return Hands::HandNames[_hand];
72 }
73
PayRate() const74 int Hands::PayRate() const
75 {
76 return Ratio[ (int)_hand ];
77 }
78
AddCard(Card * card)79 void Hands::AddCard(Card *card)
80 {
81 _cards[_next++] = card;
82 }
83
NewGame()84 void Hands::NewGame()
85 {
86 _score =0;
87 _hand = EX;
88 _next = 0;
89 // for(int i=0; i < 5; i++)
90 // _cards[i] = ( Card *)0;
91
92 }
93
Cards() const94 Card** Hands::Cards() const
95 {
96 return (Card**)_cards;
97 }
98
SortCards() const99 void Hands::SortCards() const
100 {
101 char ranks[6];
102
103 if(!_next) return;
104
105 for(int i=0; i<5; i++)
106 ranks[i] = _cards[i]->Rank();
107
108 for(int j=0; j < 4; j++) // sorting based on rank
109 for(int i=0; i < 4-j; i++)
110 {
111 if( ranks[i] < ranks[i+1] )
112 {
113 ranks[6] = ranks[i];
114 ranks[i] = ranks[i+1];
115 ranks[i+1] = ranks[6];
116 }
117 }
118 ranks[6] = '\0';
119
120 // first looking to 1p, 2p, 3k, fh and 4k
121
122 char r = ranks[0];
123 char board[4];
124 for(int i =0; i<4; i++) board[i] = '\0';
125
126 int s=1;
127 for (int i=1; i< 6; i++)
128 {
129 if( r == ranks[i] ) s++;
130 else{
131 switch(s){
132 case 2:
133 {
134 int t = (board[0] == '\0') ? 0 : 1;
135 board[t] = r;
136 }
137 break;
138 case 3:
139 board[2] = r;
140 break;
141 case 4:
142 board[3] = r;
143 break;
144 }
145 s = 1;
146 r = ranks[i];
147 }
148 }
149
150 ((Hands*)this) ->_hand = NP;
151
152 if( board[0] || board[1] || board[2] || board[3] )
153 {
154 if(board[3])
155 ((Hands*)this) ->_hand = K4;
156 else if(board[2])
157 ((Hands*)this) ->_hand = (board[0]) ? FH : K3;
158 else
159 ((Hands*)this) ->_hand = (board[1]) ? P2 : P1;
160
161 ((Hands*)this) ->ReArrange(ranks, 5, board, _hand);
162 }
163 else{
164 if(ranks[0] == (char) '\14') ranks[5] = '\1';
165 int i;
166 for(i =0; i < 4; i++)
167 if(_cards[i]->Suit() != _cards[i+1]->Suit())
168 {
169 i = 8;
170 break;
171 }
172 if( i != 8 ) ((Hands*)this) ->_hand = FL;
173 for( i = 0; i<4; i++)
174 if(ranks[i] != ranks[i+1] + 1)
175 {
176 i=8;
177 break;
178 }
179 if(i==8 && ranks[i] == '\14') // for ACE as the first one
180 for(i=1; i<4; i++)
181 if(ranks[i] != ranks[i+1] + 1)
182 {
183 i=8; break;
184 }
185 if( i != 8 )
186 {
187 ((Hands*)this) ->_hand = ( _hand == FL ) ? SF : ST;
188 if(ranks[4] == ranks[5]+1)
189 for(ranks[5] = '\14',i=0; i<5; i++)
190 ranks[i] = ranks[i+1];
191 if(ranks[0] == '\14'&& _hand == SF) ((Hands*)this) ->_hand = RF;
192 }
193 }
194
195 // calculate the score for a hand
196
197 ((Hands*)this) ->_score = ((int)_hand -1) * 7529536;
198 ((Hands*)this) ->_score+=((((ranks[0]*14)+ranks[1])*14+ranks[2])*14+ranks[3])*14+ranks[4];
199
200 // rearrange cards order
201
202 Card* tmpcards[5];
203 for(int i = 0; i < 5; i++) tmpcards[i] = _cards[i];
204 for(int i = 0; i < 5; i++)
205 for(int j=0; j<5; j++)
206 if(tmpcards[j] && ranks[i]==tmpcards[j]->Rank())
207 {
208 ((Hands*)this) ->_cards[i] = tmpcards[j];
209 tmpcards[j] = (Card *)0;
210 break;
211 }
212
213 #ifdef DEBUG
214 for(int i = 0; i < 5; i++)
215 cout << _cards[i]->Suit() << (int) _cards[i]->Rank() << " ";
216 cout << endl;
217 #endif
218
219 }
220
ReArrange(char * ranks,int nel,char * board,Hand score)221 void Hands::ReArrange(char* ranks , int nel,char* board, Hand score)
222 {
223 int i, j=0 , k = 0;
224 char tmprank[10];
225 for( i = 0; i < nel; i++) // copy all the cards to the tmprank
226 tmprank[i] = *(ranks+i);
227 tmprank[nel] = '\0';
228
229 switch(score) {
230 case P1:
231 for( k=2,i = 0; i < nel; i++)
232 if(tmprank[i] == *board) *(ranks+j) = tmprank[i], j++;
233 else *(ranks+k) = tmprank[i], k++;
234 break;
235 case P2:
236 for( k=2,i = 0; i < nel; i++)
237 if(tmprank[i] == *board) *(ranks+j) = tmprank[i], j++;
238 else if(tmprank[i] == *(board+1)) *(ranks+k) = tmprank[i], k++;
239 else *(ranks+4) = tmprank[i];
240 break;
241 case K3:
242 case FH:
243 for( k=3,i = 0; i < nel; i++)
244 if(tmprank[i] == *(board+2)) *(ranks+j) = tmprank[i], j++;
245 else *(ranks+k) = tmprank[i], k++;
246 break;
247 case K4:
248 for(i = 0; i < nel; i++)
249 if(tmprank[i] !=*(board+3) )
250 {
251 *(ranks+i) = *(board+3);
252 *(ranks+4) = tmprank[i];
253 break;
254 }
255 }
256 }
257
258