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