|
|
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[] = "@(#)support.c 5.5 (Berkeley) 6/1/90"; ! 22: #endif /* not lint */ ! 23: ! 24: #include <curses.h> ! 25: #include "deck.h" ! 26: #include "cribbage.h" ! 27: #include "cribcur.h" ! 28: ! 29: ! 30: #define NTV 10 /* number scores to test */ ! 31: ! 32: /* score to test reachability of, and order to test them in */ ! 33: int tv[ NTV ] = { 8, 7, 9, 6, 11, 12, 13, 14, 10, 5 }; ! 34: ! 35: ! 36: /* ! 37: * computer chooses what to play in pegging... ! 38: * only called if no playable card will score points ! 39: */ ! 40: ! 41: cchose( h, n, s ) ! 42: ! 43: CARD h[]; ! 44: int n; ! 45: int s; ! 46: { ! 47: register int i, j, l; ! 48: ! 49: if( n <= 1 ) return( 0 ); ! 50: if( s < 4 ) { /* try for good value */ ! 51: if( ( j = anysumto(h, n, s, 4) ) >= 0 ) return( j ); ! 52: if( ( j = anysumto(h, n, s, 3) ) >= 0 && s == 0 ) ! 53: return( j ); ! 54: } ! 55: if( s > 0 && s < 20 ) { ! 56: for( i = 1; i <= 10; i++ ) { /* try for retaliation to 31 */ ! 57: if( ( j = anysumto(h, n, s, 21-i) ) >= 0 ) { ! 58: if( ( l = numofval(h, n, i) ) > 0 ) { ! 59: if( l > 1 || VAL( h[j].rank ) != i ) return( j ); ! 60: } ! 61: } ! 62: } ! 63: } ! 64: if( s < 15 ) { ! 65: for( i = 0; i < NTV; i++ ) { /* for retaliation after 15 */ ! 66: if( ( j = anysumto(h, n, s, tv[i]) ) >= 0 ) { ! 67: if( ( l = numofval(h, n, 15-tv[i]) ) > 0 ) { ! 68: if( l > 1 || VAL( h[j].rank ) != 15-tv[i] ) return( j ); ! 69: } ! 70: } ! 71: } ! 72: } ! 73: j = -1; ! 74: for( i = n - 1; i >= 0; --i ) { /* remember: h is sorted */ ! 75: l = s + VAL( h[i].rank ); ! 76: if( l > 31 ) continue; ! 77: if( l != 5 && l != 10 && l != 21 ) { ! 78: j = i; ! 79: break; ! 80: } ! 81: } ! 82: if( j >= 0 ) return( j ); ! 83: for( i = n - 1; i >= 0; --i ) { ! 84: l = s + VAL( h[i].rank ); ! 85: if( l > 31 ) continue; ! 86: if( j < 0 ) j = i; ! 87: if( l != 5 && l != 21 ) { ! 88: j = i; ! 89: break; ! 90: } ! 91: } ! 92: return( j ); ! 93: } ! 94: ! 95: ! 96: ! 97: /* ! 98: * plyrhand: ! 99: * Evaluate and score a player hand or crib ! 100: */ ! 101: plyrhand(hand, s) ! 102: CARD hand[]; ! 103: char *s; ! 104: { ! 105: register int i, j; ! 106: register BOOLEAN win; ! 107: static char prompt[BUFSIZ]; ! 108: ! 109: prhand(hand, CINHAND, Playwin, FALSE); ! 110: (void)sprintf(prompt, "Your %s scores ", s); ! 111: i = scorehand(hand, turnover, CINHAND, strcmp(s, "crib") == 0, explain); ! 112: if ((j = number(0, 29, prompt)) == 19) ! 113: j = 0; ! 114: if (i != j) { ! 115: if (i < j) { ! 116: win = chkscr(&pscore, i); ! 117: msg("It's really only %d points; I get %d", i, 2); ! 118: if (!win) ! 119: win = chkscr(&cscore, 2); ! 120: } ! 121: else { ! 122: win = chkscr(&pscore, j); ! 123: msg("You should have taken %d, not %d!", i, j); ! 124: } ! 125: if (explain) ! 126: msg("Explanation: %s", expl); ! 127: do_wait(); ! 128: } ! 129: else ! 130: win = chkscr(&pscore, i); ! 131: return win; ! 132: } ! 133: ! 134: /* ! 135: * comphand: ! 136: * Handle scoring and displaying the computers hand ! 137: */ ! 138: comphand(h, s) ! 139: CARD h[]; ! 140: char *s; ! 141: { ! 142: register int j; ! 143: ! 144: j = scorehand(h, turnover, CINHAND, strcmp(s, "crib") == 0, FALSE); ! 145: prhand(h, CINHAND, Compwin, FALSE); ! 146: msg("My %s scores %d", s, (j == 0 ? 19 : j)); ! 147: return chkscr(&cscore, j); ! 148: } ! 149: ! 150: /* ! 151: * chkscr: ! 152: * Add inc to scr and test for > glimit, printing on the scoring ! 153: * board while we're at it. ! 154: */ ! 155: ! 156: int Lastscore[2] = {-1, -1}; ! 157: ! 158: chkscr(scr, inc) ! 159: int *scr, inc; ! 160: { ! 161: BOOLEAN myturn; ! 162: ! 163: myturn = (scr == &cscore); ! 164: if (inc != 0) { ! 165: prpeg(Lastscore[myturn], '.', myturn); ! 166: Lastscore[myturn] = *scr; ! 167: *scr += inc; ! 168: prpeg(*scr, PEG, myturn); ! 169: refresh(); ! 170: } ! 171: return (*scr >= glimit); ! 172: } ! 173: ! 174: /* ! 175: * prpeg: ! 176: * Put out the peg character on the score board and put the ! 177: * score up on the board. ! 178: */ ! 179: prpeg(score, peg, myturn) ! 180: register int score; ! 181: char peg; ! 182: BOOLEAN myturn; ! 183: { ! 184: register int y, x; ! 185: ! 186: if (!myturn) ! 187: y = SCORE_Y + 2; ! 188: else ! 189: y = SCORE_Y + 5; ! 190: ! 191: if (score <= 0 || score >= glimit) { ! 192: if (peg == '.') ! 193: peg = ' '; ! 194: if (score == 0) ! 195: x = SCORE_X + 2; ! 196: else { ! 197: x = SCORE_X + 2; ! 198: y++; ! 199: } ! 200: } ! 201: else { ! 202: x = (score - 1) % 30; ! 203: if (score > 90 || (score > 30 && score <= 60)) { ! 204: y++; ! 205: x = 29 - x; ! 206: } ! 207: x += x / 5; ! 208: x += SCORE_X + 3; ! 209: } ! 210: mvaddch(y, x, peg); ! 211: mvprintw(SCORE_Y + (myturn ? 7 : 1), SCORE_X + 10, "%3d", score); ! 212: } ! 213: ! 214: /* ! 215: * cdiscard -- the computer figures out what is the best discard for ! 216: * the crib and puts the best two cards at the end ! 217: */ ! 218: ! 219: cdiscard( mycrib ) ! 220: ! 221: BOOLEAN mycrib; ! 222: { ! 223: CARD d[ CARDS ], h[ FULLHAND ], cb[ 2 ]; ! 224: register int i, j, k; ! 225: int nc, ns; ! 226: long sums[ 15 ]; ! 227: static int undo1[15] = {0,0,0,0,0,1,1,1,1,2,2,2,3,3,4}; ! 228: static int undo2[15] = {1,2,3,4,5,2,3,4,5,3,4,5,4,5,5}; ! 229: ! 230: makedeck( d ); ! 231: nc = CARDS; ! 232: for( i = 0; i < knownum; i++ ) { /* get all other cards */ ! 233: remove( known[i], d, nc-- ); ! 234: } ! 235: for( i = 0; i < 15; i++ ) sums[i] = 0L; ! 236: ns = 0; ! 237: for( i = 0; i < (FULLHAND - 1); i++ ) { ! 238: cb[0] = chand[i]; ! 239: for( j = i + 1; j < FULLHAND; j++ ) { ! 240: cb[1] = chand[j]; ! 241: for( k = 0; k < FULLHAND; k++ ) h[k] = chand[k]; ! 242: remove( chand[i], h, FULLHAND ); ! 243: remove( chand[j], h, FULLHAND - 1 ); ! 244: for( k = 0; k < nc; k++ ) { ! 245: sums[ns] += scorehand( h, d[k], CINHAND, TRUE, FALSE ); ! 246: if( mycrib ) sums[ns] += adjust( cb, d[k] ); ! 247: else sums[ns] -= adjust( cb, d[k] ); ! 248: } ! 249: ++ns; ! 250: } ! 251: } ! 252: j = 0; ! 253: for( i = 1; i < 15; i++ ) if( sums[i] > sums[j] ) j = i; ! 254: for( k = 0; k < FULLHAND; k++ ) h[k] = chand[k]; ! 255: remove( h[ undo1[j] ], chand, FULLHAND ); ! 256: remove( h[ undo2[j] ], chand, FULLHAND - 1 ); ! 257: chand[4] = h[ undo1[j] ]; ! 258: chand[5] = h[ undo2[j] ]; ! 259: } ! 260: ! 261: ! 262: ! 263: /* ! 264: * returns true if some card in hand can be played without exceeding 31 ! 265: */ ! 266: ! 267: anymove( hand, n, sum ) ! 268: ! 269: CARD hand[]; ! 270: int n; ! 271: int sum; ! 272: { ! 273: register int i, j; ! 274: ! 275: if( n < 1 ) return( FALSE ); ! 276: j = hand[0].rank; ! 277: for( i = 1; i < n; i++ ) { ! 278: if( hand[i].rank < j ) j = hand[i].rank; ! 279: } ! 280: return( sum + VAL( j ) <= 31 ); ! 281: } ! 282: ! 283: ! 284: ! 285: /* ! 286: * anysumto returns the index (0 <= i < n) of the card in hand that brings ! 287: * the s up to t, or -1 if there is none ! 288: */ ! 289: ! 290: anysumto( hand, n, s, t ) ! 291: ! 292: CARD hand[]; ! 293: int n; ! 294: int s, t; ! 295: { ! 296: register int i; ! 297: ! 298: for( i = 0; i < n; i++ ) { ! 299: if( s + VAL( hand[i].rank ) == t ) return( i ); ! 300: } ! 301: return( -1 ); ! 302: } ! 303: ! 304: ! 305: ! 306: ! 307: /* ! 308: * return the number of cards in h having the given rank value ! 309: */ ! 310: ! 311: numofval( h, n, v ) ! 312: ! 313: CARD h[]; ! 314: int n; ! 315: int v; ! 316: { ! 317: register int i, j; ! 318: ! 319: j = 0; ! 320: for( i = 0; i < n; i++ ) { ! 321: if( VAL( h[i].rank ) == v ) ++j; ! 322: } ! 323: return( j ); ! 324: } ! 325: ! 326: ! 327: ! 328: /* ! 329: * makeknown remembers all n cards in h for future recall ! 330: */ ! 331: ! 332: makeknown( h, n ) ! 333: ! 334: CARD h[]; ! 335: int n; ! 336: { ! 337: register int i; ! 338: ! 339: for( i = 0; i < n; i++ ) { ! 340: known[ knownum++ ] = h[i]; ! 341: } ! 342: } ! 343:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.