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