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