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