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
dble(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
dblgood(void)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
freemen(int b)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
trapped(int n,int inc)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
eval(void)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