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 
34 #ifndef lint
35 #if 0
36 static char sccsid[] = "@(#)extra.c	8.1 (Berkeley) 5/31/93";
37 #endif
38 static const char rcsid[] =
39  "$FreeBSD: src/games/backgammon/backgammon/extra.c,v 1.4 1999/11/30 03:48:22 billf Exp $";
40 #endif /* not lint */
41 
42 #include "back.h"
43 
44 #ifdef DEBUG
45 #include <stdio.h>
46 FILE	*trace;
47 #endif
48 
49 /*
50  * dble()
51  *	Have the current player double and ask opponent to accept.
52  */
53 
54 dble ()  {
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 dblgood ()  {
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
140 						 * according to position
141 						 * judgments */
142 
143 						/* check men moving off
144 						 * board */
145 	if (OFFC > -15 || OFFO > -15)  {
146 		if (OFFC < 0 && OFFO < 0)  {
147 			OFFC += 15;
148 			OFFO += 15;
149 			n +=((OFFC-OFFO)*7)/2;
150 		} else if (OFFC < 0)  {
151 			OFFC += 15;
152 			n -= OFFO*7/2;
153 		} else if (OFFO < 0)  {
154 			OFFO += 15;
155 			n += OFFC*7/2;
156 		}
157 		if (OFFC < 8 && OFFO > 8)
158 			n -= 7;
159 		if (OFFC < 10 && OFFO > 10)
160 			n -= 7;
161 		if (OFFC < 12 && OFFO > 12)
162 			n -= 7;
163 		if (OFFO < 8 && OFFC > 8)
164 			n += 7;
165 		if (OFFO < 10 && OFFC > 10)
166 			n += 7;
167 		if (OFFO < 12 && OFFC > 12)
168 			n += 7;
169 		n += ((OFFC-OFFO)*7)/2;
170 	}
171 
172 #ifdef DEBUG
173 	fprintf (trace,"off = %d, ",n);
174 #endif
175 
176 						/* see if men are trapped */
177 	n -= freemen(bar);
178 	n += freemen(home);
179 	n += trapped(home,-cturn);
180 	n -= trapped(bar,cturn);
181 
182 #ifdef DEBUG
183 	fprintf (trace,"free = %d\n",n);
184 	fprintf (trace,"\tOFFC = %d, OFFO = %d\n",OFFC,OFFO);
185 	fflush (trace);
186 #endif
187 
188 						/* double if 2-3 moves ahead */
189 	if (n > 10+rnum(7))
190 		return(1);
191 	return (0);
192 }
193 
194 freemen (b)
195 int	b;
196 
197 {
198 	int		i, inc, lim;
199 
200 	odds(0,0,0);
201 	if (board[b] == 0)
202 		return (0);
203 	inc = (b == 0? 1: -1);
204 	lim = (b == 0? 7: 18);
205 	for (i = b+inc; i != lim; i += inc)
206 		if (board[i]*inc < -1)
207 			odds(abs(b-i),0,abs(board[b]));
208 	if (abs(board[b]) == 1)
209 		return ((36-count())/5);
210 	return (count()/5);
211 }
212 
213 trapped (n,inc)
214 int	n, inc;
215 
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 eval ()  {
241 
242 	int		i, j;
243 
244 	for (j = i = 0; i < 26; i++)
245 		j += (board[i] >= 0 ? i*board[i] : (25-i)*board[i]);
246 
247 	if (off[1] >= 0)
248 		j += 25*off[1];
249 	else
250 		j += 25*(off[1]+15);
251 
252 	if (off[0] >= 0)
253 		j -= 25*off[0];
254 	else
255 		j -= 25*(off[0]+15);
256 	return (j);
257 }
258