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