|
|
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.