1 /* $OpenBSD: extra.c,v 1.8 2015/11/30 08:19:25 tb 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 "back.h"
33 #include "backlocal.h"
34
35 /*
36 * dble()
37 * Have the current player double and ask opponent to accept.
38 */
39
40 void
dble(void)41 dble(void)
42 {
43 int resp; /* response to y/n */
44
45 for (;;) {
46 addstr(" doubles."); /* indicate double */
47
48 if (cturn == -pnum) { /* see if computer accepts */
49 if (dblgood()) { /* guess not */
50 addstr(" Declined.\n");
51 nexturn();
52 cturn *= -2; /* indicate loss */
53 return;
54 } else {/* computer accepts */
55 addstr(" Accepted.\n");
56 gvalue *= 2; /* double game value */
57 dlast = cturn;
58 gwrite();
59 return;
60 }
61 }
62 /* ask if player accepts */
63 printw(" Does %s accept?", cturn == 1 ? color[2] : color[3]);
64
65 /* get response from yorn; a "2" means he said "p" to print board. */
66 if ((resp = yorn ('r')) == 2) {
67 addstr(" Reprint.\n");
68 moveplayers();
69 wrboard();
70 addstr(*Colorptr);
71 continue;
72 }
73 /* check response */
74 if (resp) {
75 /* accepted */
76 gvalue *= 2;
77 dlast = cturn;
78 gwrite();
79 return;
80 }
81 nexturn(); /* declined */
82 cturn *= -2;
83 return;
84 }
85 }
86
87 /*
88 * dblgood ()
89 * Returns 1 if the computer would double in this position. This
90 * is not an exact science. The computer will decline a double that he
91 * would have made. Accumulated judgments are kept in the variable n,
92 * which is in "pips", i.e., the position of each man summed over all
93 * men, with opponent's totals negative. Thus, n should have a positive
94 * value of 7 for each move ahead, or a negative value of 7 for each one
95 * behind.
96 */
97
98 int
dblgood(void)99 dblgood(void)
100 {
101 int n; /* accumulated judgment */
102 int OFFC = *offptr; /* no. of computer's men off */
103 int OFFO = *offopp; /* no. of player's men off */
104
105 #ifdef DEBUG
106 int i;
107 if (ftrace == NULL)
108 ftrace = fopen("bgtrace", "w");
109 printf ("fopen\n");
110 #endif
111
112 /* get real pip value */
113 n = eval() * cturn;
114 #ifdef DEBUG
115 fputs("\nDoubles:\nBoard: ", ftrace);
116 for (i = 0; i < 26; i++)
117 fprintf(ftrace, " %d", board[i]);
118 fprintf(ftrace, "\n\tpip = %d, ", n);
119 #endif
120
121 /* below adjusts pip value according to position judgments */
122
123 /* check men moving off board */
124 if (OFFC > -15 || OFFO > -15) {
125 if (OFFC < 0 && OFFO < 0) {
126 OFFC += 15;
127 OFFO += 15;
128 n +=((OFFC - OFFO) * 7) / 2;
129 } else if (OFFC < 0) {
130 OFFC += 15;
131 n -= OFFO * 7 / 2;
132 } else if (OFFO < 0) {
133 OFFO += 15;
134 n += OFFC * 7 / 2;
135 }
136 if (OFFC < 8 && OFFO > 8)
137 n -= 7;
138 if (OFFC < 10 && OFFO > 10)
139 n -= 7;
140 if (OFFC < 12 && OFFO > 12)
141 n -= 7;
142 if (OFFO < 8 && OFFC > 8)
143 n += 7;
144 if (OFFO < 10 && OFFC > 10)
145 n += 7;
146 if (OFFO < 12 && OFFC > 12)
147 n += 7;
148 n += ((OFFC - OFFO) * 7) / 2;
149 }
150
151 #ifdef DEBUG
152 fprintf(ftrace, "off = %d, ", n);
153 #endif
154
155 /* see if men are trapped */
156 n -= freemen(bar);
157 n += freemen(home);
158 n += trapped(home, -cturn);
159 n -= trapped(bar, cturn);
160
161 #ifdef DEBUG
162 fprintf(ftrace, "free = %d\n", n);
163 fprintf(ftrace, "\tOFFC = %d, OFFO = %d\n", OFFC, OFFO);
164 fflush(ftrace);
165 #endif
166
167 /* double if 2-3 moves ahead */
168 if (n > (int)(10 + rnum(7)))
169 return(1);
170 return(0);
171 }
172
173 int
freemen(int b)174 freemen(int b)
175 {
176 int i, inc, lim;
177
178 odds(0, 0, 0);
179 if (board[b] == 0)
180 return (0);
181 inc = (b == 0 ? 1 : -1);
182 lim = (b == 0 ? 7 : 18);
183 for (i = b + inc; i != lim; i += inc)
184 if (board[i] * inc < -1)
185 odds(abs(b - i), 0, abs(board[b]));
186 if (abs(board[b]) == 1)
187 return ((36 - count()) / 5);
188 return (count() / 5);
189 }
190
191 int
trapped(int n,int inc)192 trapped(int n, int inc)
193 {
194 int i, j, k;
195 int c, l, ct;
196
197 ct = 0;
198 l = n + 7 * inc;
199 for (i = n + inc; i != l; i += inc) {
200 odds(0, 0, 0);
201 c = abs(i - l);
202 if (board[i] * inc > 0) {
203 for (j = c; j < 13; j++)
204 if (board[i + inc * j] * inc < -1) {
205 if (j < 7)
206 odds(j, 0, 1);
207 for (k = 1; k < 7 && k < j; k++)
208 if (j - k < 7)
209 odds(k, j - k, 1);
210 }
211 ct += abs(board[i]) * (36 - count());
212 }
213 }
214 return(ct / 5);
215 }
216
217 int
eval(void)218 eval(void)
219 {
220 int i, j;
221
222 for (j = i = 0; i < 26; i++)
223 j += (board[i] >= 0 ? i * board[i] : (25 - i) * board[i]);
224
225 if (off[1] >= 0)
226 j += 25 * off[1];
227 else
228 j += 25 * (off[1] + 15);
229
230 if (off[0] >= 0)
231 j -= 25 * off[0];
232 else
233 j -= 25 * (off[0] + 15);
234 return(j);
235 }
236