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

Defined functions

adjust defined in line 313; used 2 times
fifteens defined in line 150; used 1 times
pairuns defined in line 195; used 1 times
pegscore defined in line 270; used 2 times
scorehand defined in line 75; used 9 times

Defined variables

crbescr defined in line 23; used 1 times
crbnescr defined in line 44; used 1 times
ichoose2 defined in line 66; used 3 times
pairpoints defined in line 67; used 3 times
runpoints defined in line 67; used 3 times
sccsid defined in line 8; never used
Last modified: 1985-05-31
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3173
Valid CSS Valid XHTML 1.0 Strict