xref: /netbsd/games/backgammon/backgammon/extra.c (revision bf9ec67e)
1 /*	$NetBSD: extra.c,v 1.4 1997/10/10 08:59:36 lukem Exp $	*/
2 
3 /*
4  * Copyright (c) 1980, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the University of
18  *	California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 
36 #include <sys/cdefs.h>
37 #ifndef lint
38 #if 0
39 static char sccsid[] = "@(#)extra.c	8.1 (Berkeley) 5/31/93";
40 #else
41 __RCSID("$NetBSD: extra.c,v 1.4 1997/10/10 08:59:36 lukem Exp $");
42 #endif
43 #endif /* not lint */
44 
45 #include "back.h"
46 #include "backlocal.h"
47 
48 #ifdef DEBUG
49 FILE   *trace;
50 #endif
51 
52 /*
53  * dble()
54  *	Have the current player double and ask opponent to accept.
55  */
56 
57 void
58 dble()
59 {
60 	int     resp;		/* response to y/n */
61 
62 	for (;;) {
63 		writel(" doubles.");	/* indicate double */
64 
65 		if (cturn == -pnum) {	/* see if computer accepts */
66 			if (dblgood()) {	/* guess not */
67 				writel("  Declined.\n");
68 				nexturn();
69 				cturn *= -2;	/* indicate loss */
70 				return;
71 			} else {/* computer accepts */
72 				writel("  Accepted.\n");
73 				gvalue *= 2;	/* double game value */
74 				dlast = cturn;
75 				if (tflag)
76 					gwrite();
77 				return;
78 			}
79 		}
80 		/* ask if player accepts */
81 		writel("  Does ");
82 		writel(cturn == 1 ? color[2] : color[3]);
83 		writel(" accept?");
84 
85 		/* get response from yorn, a "2" means he said "p" for print
86 		 * board. */
87 		if ((resp = yorn('R')) == 2) {
88 			writel("  Reprint.\n");
89 			buflush();
90 			wrboard();
91 			writel(*Colorptr);
92 			continue;
93 		}
94 		/* check response */
95 		if (resp) {
96 			/* accepted */
97 			gvalue *= 2;
98 			dlast = cturn;
99 			if (tflag)
100 				gwrite();
101 			return;
102 		}
103 		nexturn();	/* declined */
104 		cturn *= -2;
105 		return;
106 	}
107 }
108 /*
109  * dblgood ()
110  *	Returns 1 if the computer would double in this position.  This
111  * is not an exact science.  The computer will decline a double that he
112  * would have made.  Accumulated judgments are kept in the variable n,
113  * which is in "pips", i.e., the position of each man summed over all
114  * men, with opponent's totals negative.  Thus, n should have a positive
115  * value of 7 for each move ahead, or a negative value of 7 for each one
116  * behind.
117  */
118 
119 int
120 dblgood()
121 {
122 	int     n;		/* accumulated judgment */
123 	int     OFFC = *offptr;	/* no. of computer's men off */
124 	int     OFFO = *offopp;	/* no. of player's men off */
125 
126 #ifdef DEBUG
127 	int     i;
128 	if (trace == NULL)
129 		trace = fopen("bgtrace", "w");
130 #endif
131 
132 	/* get real pip value */
133 	n = eval() * cturn;
134 #ifdef DEBUG
135 	fputs("\nDoubles:\nBoard: ", trace);
136 	for (i = 0; i < 26; i++)
137 		fprintf(trace, " %d", board[i]);
138 	fprintf(trace, "\n\tpip = %d, ", n);
139 #endif
140 
141 	/* below adjusts pip value according to position judgments */
142 
143 	/* check men moving off board */
144 	if (OFFC > -15 || OFFO > -15) {
145 		if (OFFC < 0 && OFFO < 0) {
146 			OFFC += 15;
147 			OFFO += 15;
148 			n += ((OFFC - OFFO) * 7) / 2;
149 		} else
150 			if (OFFC < 0) {
151 				OFFC += 15;
152 				n -= OFFO * 7 / 2;
153 			} else
154 				if (OFFO < 0) {
155 					OFFO += 15;
156 					n += OFFC * 7 / 2;
157 				}
158 		if (OFFC < 8 && OFFO > 8)
159 			n -= 7;
160 		if (OFFC < 10 && OFFO > 10)
161 			n -= 7;
162 		if (OFFC < 12 && OFFO > 12)
163 			n -= 7;
164 		if (OFFO < 8 && OFFC > 8)
165 			n += 7;
166 		if (OFFO < 10 && OFFC > 10)
167 			n += 7;
168 		if (OFFO < 12 && OFFC > 12)
169 			n += 7;
170 		n += ((OFFC - OFFO) * 7) / 2;
171 	}
172 #ifdef DEBUG
173 	fprintf(trace, "off = %d, ", n);
174 #endif
175 
176 	/* see if men are trapped */
177 	n -= freemen(bar);
178 	n += freemen(home);
179 	n += trapped(home, -cturn);
180 	n -= trapped(bar, cturn);
181 
182 #ifdef DEBUG
183 	fprintf(trace, "free = %d\n", n);
184 	fprintf(trace, "\tOFFC = %d, OFFO = %d\n", OFFC, OFFO);
185 	fflush(trace);
186 #endif
187 
188 	/* double if 2-3 moves ahead */
189 	if (n > 10 + rnum(7))
190 		return (1);
191 	return (0);
192 }
193 
194 int
195 freemen(b)
196 	int     b;
197 {
198 	int     i, inc, lim;
199 
200 	odds(0, 0, 0);
201 	if (board[b] == 0)
202 		return (0);
203 	inc = (b == 0 ? 1 : -1);
204 	lim = (b == 0 ? 7 : 18);
205 	for (i = b + inc; i != lim; i += inc)
206 		if (board[i] * inc < -1)
207 			odds(abs(b - i), 0, abs(board[b]));
208 	if (abs(board[b]) == 1)
209 		return ((36 - count()) / 5);
210 	return (count() / 5);
211 }
212 
213 int
214 trapped(n, inc)
215 	int     n, inc;
216 {
217 	int     i, j, k;
218 	int     c, l, ct;
219 
220 	ct = 0;
221 	l = n + 7 * inc;
222 	for (i = n + inc; i != l; i += inc) {
223 		odds(0, 0, 0);
224 		c = abs(i - l);
225 		if (board[i] * inc > 0) {
226 			for (j = c; j < 13; j++)
227 				if (board[i + inc * j] * inc < -1) {
228 					if (j < 7)
229 						odds(j, 0, 1);
230 					for (k = 1; k < 7 && k < j; k++)
231 						if (j - k < 7)
232 							odds(k, j - k, 1);
233 				}
234 			ct += abs(board[i]) * (36 - count());
235 		}
236 	}
237 	return (ct / 5);
238 }
239 
240 int
241 eval()
242 {
243 	int     i, j;
244 
245 	for (j = i = 0; i < 26; i++)
246 		j += (board[i] >= 0 ? i * board[i] : (25 - i) * board[i]);
247 
248 	if (off[1] >= 0)
249 		j += 25 * off[1];
250 	else
251 		j += 25 * (off[1] + 15);
252 
253 	if (off[0] >= 0)
254 		j -= 25 * off[0];
255 	else
256 		j -= 25 * (off[0] + 15);
257 	return (j);
258 }
259