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