Annotation of 42BSD/games/cribbage/score.c, revision 1.1

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

unix.superglobalmegacorp.com

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