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