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

unix.superglobalmegacorp.com

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