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