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 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 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 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 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 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