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