Commit | Line | Data |
---|---|---|
3f03c0c5 | 1 | /*- |
44837faf KB |
2 | * Copyright (c) 1980, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
bf870064 | 4 | * |
7c5ab767 | 5 | * %sccs.include.redist.c% |
6cca9b39 KM |
6 | */ |
7 | ||
8 | #ifndef lint | |
44837faf | 9 | static char sccsid[] = "@(#)score.c 8.1 (Berkeley) %G%"; |
bf870064 | 10 | #endif /* not lint */ |
36235584 | 11 | |
3f03c0c5 KB |
12 | #include <curses.h> |
13 | #include <stdio.h> | |
14 | #include <stdlib.h> | |
15 | #include <string.h> | |
36235584 | 16 | |
3f03c0c5 KB |
17 | #include "deck.h" |
18 | #include "cribbage.h" | |
36235584 KA |
19 | |
20 | /* | |
21 | * the following arrays give the sum of the scores of the (50 2)*48 = 58800 | |
22 | * hands obtainable for the crib given the two cards whose ranks index the | |
23 | * array. the two arrays are for the case where the suits are equal and | |
24 | * not equal respectively | |
25 | */ | |
3f03c0c5 | 26 | long crbescr[169] = { |
36235584 KA |
27 | -10000, 271827, 278883, 332319, 347769, 261129, 250653, 253203, 248259, |
28 | 243435, 256275, 237435, 231051, -10000, -10000, 412815, 295707, 349497, | |
29 | 267519, 262521, 259695, 254019, 250047, 262887, 244047, 237663, -10000, | |
30 | -10000, -10000, 333987, 388629, 262017, 266787, 262971, 252729, 254475, | |
31 | 267315, 248475, 242091, -10000, -10000, -10000, -10000, 422097, 302787, | |
32 | 256437, 263751, 257883, 254271, 267111, 248271, 241887, -10000, -10000, | |
33 | -10000, -10000, -10000, 427677, 387837, 349173, 347985, 423861, 436701, | |
34 | 417861, 411477, -10000, -10000, -10000, -10000, -10000, -10000, 336387, | |
35 | 298851, 338667, 236487, 249327, 230487, 224103, -10000, -10000, -10000, | |
36 | -10000, -10000, -10000, -10000, 408483, 266691, 229803, 246195, 227355, | |
37 | 220971, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, | |
38 | 300675, 263787, 241695, 226407, 220023, -10000, -10000, -10000, -10000, | |
39 | -10000, -10000, -10000, -10000, -10000, 295635, 273543, 219771, 216939, | |
40 | -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, | |
41 | -10000, 306519, 252747, 211431, -10000, -10000, -10000, -10000, -10000, | |
42 | -10000, -10000, -10000, -10000, -10000, -10000, 304287, 262971, -10000, | |
43 | -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, | |
44 | -10000, -10000, 244131, -10000, -10000, -10000, -10000, -10000, -10000, | |
3f03c0c5 KB |
45 | -10000, -10000, -10000, -10000, -10000, -10000, -10000 |
46 | }; | |
36235584 | 47 | |
3f03c0c5 | 48 | long crbnescr[169] = { |
36235584 KA |
49 | 325272, 260772, 267828, 321264, 336714, 250074, 239598, 242148, 237204, |
50 | 232380, 246348, 226380, 219996, -10000, 342528, 401760, 284652, 338442, | |
51 | 256464, 251466, 248640, 242964, 238992, 252960, 232992, 226608, -10000, | |
52 | -10000, 362280, 322932, 377574, 250962, 255732, 251916, 241674, 243420, | |
53 | 257388, 237420, 231036, -10000, -10000, -10000, 360768, 411042, 291732, | |
54 | 245382, 252696, 246828, 243216, 257184, 237216, 230832, -10000, -10000, | |
55 | -10000, -10000, 528768, 416622, 376782, 338118, 336930, 412806, 426774, | |
56 | 406806, 400422, -10000, -10000, -10000, -10000, -10000, 369864, 325332, | |
57 | 287796, 327612, 225432, 239400, 219432, 213048, -10000, -10000, -10000, | |
58 | -10000, -10000, -10000, 359160, 397428, 255636, 218748, 236268, 216300, | |
59 | 209916, -10000, -10000, -10000, -10000, -10000, -10000, -10000, 331320, | |
60 | 289620, 252732, 231768, 215352, 208968, -10000, -10000, -10000, -10000, | |
61 | -10000, -10000, -10000, -10000, 325152, 284580, 263616, 208716, 205884, | |
62 | -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, | |
63 | 321240, 296592, 241692, 200376, -10000, -10000, -10000, -10000, -10000, | |
64 | -10000, -10000, -10000, -10000, -10000, 348600, 294360, 253044, -10000, | |
65 | -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, | |
66 | -10000, 308664, 233076, -10000, -10000, -10000, -10000, -10000, -10000, | |
3f03c0c5 KB |
67 | -10000, -10000, -10000, -10000, -10000, -10000, 295896 |
68 | }; | |
36235584 | 69 | |
3f03c0c5 KB |
70 | static int ichoose2[5] = { 0, 0, 2, 6, 12 }; |
71 | static int pairpoints, runpoints; /* Globals from pairuns. */ | |
36235584 KA |
72 | |
73 | /* | |
56b49d73 KA |
74 | * scorehand: |
75 | * Score the given hand of n cards and the starter card. | |
76 | * n must be <= 4 | |
36235584 | 77 | */ |
3f03c0c5 | 78 | int |
56b49d73 | 79 | scorehand(hand, starter, n, crb, do_explain) |
3f03c0c5 KB |
80 | register CARD hand[]; |
81 | CARD starter; | |
82 | int n; | |
83 | BOOLEAN crb; /* true if scoring crib */ | |
84 | BOOLEAN do_explain; /* true if must explain this hand */ | |
36235584 | 85 | { |
3f03c0c5 KB |
86 | register int i, k; |
87 | register int score; | |
88 | register BOOLEAN flag; | |
89 | CARD h[(CINHAND + 1)]; | |
90 | char buf[32]; | |
36235584 KA |
91 | |
92 | expl[0] = NULL; /* initialize explanation */ | |
93 | score = 0; | |
f870d435 | 94 | flag = TRUE; |
36235584 | 95 | k = hand[0].suit; |
3f03c0c5 KB |
96 | for (i = 0; i < n; i++) { /* check for flush */ |
97 | flag = (flag && (hand[i].suit == k)); | |
98 | if (hand[i].rank == JACK) /* check for his nibs */ | |
99 | if (hand[i].suit == starter.suit) { | |
100 | score++; | |
101 | if (do_explain) | |
102 | strcat(expl, "His Nobs"); | |
103 | } | |
104 | h[i] = hand[i]; | |
36235584 | 105 | } |
56b49d73 KA |
106 | |
107 | if (flag && n >= CINHAND) { | |
56b49d73 | 108 | if (do_explain && expl[0] != NULL) |
3f03c0c5 KB |
109 | strcat(expl, ", "); |
110 | if (starter.suit == k) { | |
111 | score += 5; | |
112 | if (do_explain) | |
113 | strcat(expl, "Five-flush"); | |
114 | } else | |
115 | if (!crb) { | |
116 | score += 4; | |
117 | if (do_explain && expl[0] != NULL) | |
118 | strcat(expl, ", Four-flush"); | |
119 | else | |
120 | strcpy(expl, "Four-flush"); | |
121 | } | |
36235584 | 122 | } |
56b49d73 | 123 | if (do_explain && expl[0] != NULL) |
3f03c0c5 | 124 | strcat(expl, ", "); |
56b49d73 | 125 | h[n] = starter; |
3f03c0c5 | 126 | sorthand(h, n + 1); /* sort by rank */ |
56b49d73 | 127 | i = 2 * fifteens(h, n + 1); |
36235584 | 128 | score += i; |
56b49d73 | 129 | if (do_explain) |
3f03c0c5 KB |
130 | if (i > 0) { |
131 | (void) sprintf(buf, "%d points in fifteens", i); | |
132 | strcat(expl, buf); | |
133 | } else | |
134 | strcat(expl, "No fifteens"); | |
56b49d73 | 135 | i = pairuns(h, n + 1); |
36235584 | 136 | score += i; |
56b49d73 | 137 | if (do_explain) |
3f03c0c5 KB |
138 | if (i > 0) { |
139 | (void) sprintf(buf, ", %d points in pairs, %d in runs", | |
140 | pairpoints, runpoints); | |
141 | strcat(expl, buf); | |
142 | } else | |
143 | strcat(expl, ", No pairs/runs"); | |
144 | return (score); | |
36235584 KA |
145 | } |
146 | ||
36235584 | 147 | /* |
56b49d73 KA |
148 | * fifteens: |
149 | * Return number of fifteens in hand of n cards | |
36235584 | 150 | */ |
3f03c0c5 | 151 | int |
56b49d73 | 152 | fifteens(hand, n) |
3f03c0c5 KB |
153 | register CARD hand[]; |
154 | int n; | |
36235584 | 155 | { |
3f03c0c5 KB |
156 | register int *sp, *np; |
157 | register int i; | |
158 | register CARD *endp; | |
159 | static int sums[15], nsums[15]; | |
56b49d73 KA |
160 | |
161 | np = nsums; | |
162 | sp = sums; | |
163 | i = 16; | |
164 | while (--i) { | |
3f03c0c5 KB |
165 | *np++ = 0; |
166 | *sp++ = 0; | |
56b49d73 KA |
167 | } |
168 | for (endp = &hand[n]; hand < endp; hand++) { | |
3f03c0c5 KB |
169 | i = hand->rank + 1; |
170 | if (i > 10) | |
171 | i = 10; | |
172 | np = &nsums[i]; | |
173 | np[-1]++; /* one way to make this */ | |
174 | sp = sums; | |
175 | while (i < 15) { | |
176 | *np++ += *sp++; | |
177 | i++; | |
178 | } | |
179 | sp = sums; | |
180 | np = nsums; | |
181 | i = 16; | |
182 | while (--i) | |
183 | *sp++ = *np++; | |
36235584 | 184 | } |
56b49d73 | 185 | return sums[14]; |
36235584 KA |
186 | } |
187 | ||
36235584 KA |
188 | /* |
189 | * pairuns returns the number of points in the n card sorted hand | |
190 | * due to pairs and runs | |
191 | * this routine only works if n is strictly less than 6 | |
192 | * sets the globals pairpoints and runpoints appropriately | |
193 | */ | |
3f03c0c5 KB |
194 | int |
195 | pairuns(h, n) | |
196 | CARD h[]; | |
197 | int n; | |
36235584 | 198 | { |
3f03c0c5 KB |
199 | register int i; |
200 | int runlength, runmult, lastmult, curmult; | |
201 | int mult1, mult2, pair1, pair2; | |
202 | BOOLEAN run; | |
36235584 KA |
203 | |
204 | run = TRUE; | |
205 | runlength = 1; | |
206 | mult1 = 1; | |
207 | pair1 = -1; | |
208 | mult2 = 1; | |
209 | pair2 = -1; | |
210 | curmult = runmult = 1; | |
3f03c0c5 KB |
211 | for (i = 1; i < n; i++) { |
212 | lastmult = curmult; | |
213 | if (h[i].rank == h[i - 1].rank) { | |
214 | if (pair1 < 0) { | |
215 | pair1 = h[i].rank; | |
216 | mult1 = curmult = 2; | |
217 | } else { | |
218 | if (h[i].rank == pair1) { | |
219 | curmult = ++mult1; | |
220 | } else { | |
221 | if (pair2 < 0) { | |
222 | pair2 = h[i].rank; | |
223 | mult2 = curmult = 2; | |
224 | } else { | |
225 | curmult = ++mult2; | |
226 | } | |
227 | } | |
36235584 | 228 | } |
3f03c0c5 KB |
229 | if (i == (n - 1) && run) { |
230 | runmult *= curmult; | |
36235584 | 231 | } |
3f03c0c5 KB |
232 | } else { |
233 | curmult = 1; | |
234 | if (h[i].rank == h[i - 1].rank + 1) { | |
235 | if (run) { | |
236 | ++runlength; | |
237 | } else { | |
238 | /* only if old short */ | |
239 | if (runlength < 3) { | |
240 | run = TRUE; | |
241 | runlength = 2; | |
242 | runmult = 1; | |
243 | } | |
244 | } | |
245 | runmult *= lastmult; | |
246 | } else { | |
247 | /* if just ended */ | |
248 | if (run) | |
249 | runmult *= lastmult; | |
250 | run = FALSE; | |
36235584 | 251 | } |
36235584 | 252 | } |
36235584 | 253 | } |
3f03c0c5 KB |
254 | pairpoints = ichoose2[mult1] + ichoose2[mult2]; |
255 | runpoints = (runlength >= 3 ? runlength * runmult : 0); | |
256 | return (pairpoints + runpoints); | |
36235584 KA |
257 | } |
258 | ||
36235584 KA |
259 | /* |
260 | * pegscore tells how many points crd would get if played after | |
261 | * the n cards in tbl during pegging | |
262 | */ | |
3f03c0c5 KB |
263 | int |
264 | pegscore(crd, tbl, n, sum) | |
265 | CARD crd, tbl[]; | |
266 | int n, sum; | |
36235584 | 267 | { |
3f03c0c5 KB |
268 | BOOLEAN got[RANKS]; |
269 | register int i, j, scr; | |
270 | int k, lo, hi; | |
271 | ||
272 | sum += VAL(crd.rank); | |
273 | if (sum > 31) | |
274 | return (-1); | |
275 | if (sum == 31 || sum == 15) | |
276 | scr = 2; | |
277 | else | |
278 | scr = 0; | |
279 | if (!n) | |
280 | return (scr); | |
36235584 | 281 | j = 1; |
3f03c0c5 KB |
282 | while ((crd.rank == tbl[n - j].rank) && (n - j >= 0)) |
283 | ++j; | |
284 | if (j > 1) | |
285 | return (scr + ichoose2[j]); | |
286 | if (n < 2) | |
287 | return (scr); | |
36235584 | 288 | lo = hi = crd.rank; |
3f03c0c5 KB |
289 | for (i = 0; i < RANKS; i++) |
290 | got[i] = FALSE; | |
291 | got[crd.rank] = TRUE; | |
36235584 | 292 | k = -1; |
3f03c0c5 KB |
293 | for (i = n - 1; i >= 0; --i) { |
294 | if (got[tbl[i].rank]) | |
295 | break; | |
296 | got[tbl[i].rank] = TRUE; | |
297 | if (tbl[i].rank < lo) | |
298 | lo = tbl[i].rank; | |
299 | if (tbl[i].rank > hi) | |
300 | hi = tbl[i].rank; | |
301 | for (j = lo; j <= hi; j++) | |
302 | if (!got[j]) | |
303 | break; | |
304 | if (j > hi) | |
305 | k = hi - lo + 1; | |
36235584 | 306 | } |
3f03c0c5 KB |
307 | if (k >= 3) |
308 | return (scr + k); | |
309 | else | |
310 | return (scr); | |
36235584 KA |
311 | } |
312 | ||
36235584 KA |
313 | /* |
314 | * adjust takes a two card hand that will be put in the crib | |
315 | * and returns an adjusted normalized score for the number of | |
316 | * points such a crib will get. | |
317 | */ | |
3f03c0c5 KB |
318 | int |
319 | adjust(cb, tnv) | |
320 | CARD cb[], tnv; | |
36235584 | 321 | { |
3f03c0c5 KB |
322 | long scr; |
323 | int i, c0, c1; | |
36235584 KA |
324 | |
325 | c0 = cb[0].rank; | |
326 | c1 = cb[1].rank; | |
3f03c0c5 KB |
327 | if (c0 > c1) { |
328 | i = c0; | |
329 | c0 = c1; | |
330 | c1 = i; | |
36235584 | 331 | } |
3f03c0c5 KB |
332 | if (cb[0].suit != cb[1].suit) |
333 | scr = crbnescr[RANKS * c0 + c1]; | |
334 | else | |
335 | scr = crbescr[RANKS * c0 + c1]; | |
336 | if (scr <= 0) { | |
337 | printf("\nADJUST: internal error %d %d\n", c0, c1); | |
338 | exit(93); | |
36235584 | 339 | } |
3f03c0c5 | 340 | return ((scr + 29400) / 58800); |
36235584 | 341 | } |