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