Annotation of 43BSDTahoe/games/cribbage/score.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.