1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)extra.c	5.3 (Berkeley) 06/18/88";
20 #endif /* not lint */
21 
22 #include "back.h"
23 
24 #ifdef DEBUG
25 #include <stdio.h>
26 FILE	*trace;
27 #endif
28 
29 /*
30  * dble()
31  *	Have the current player double and ask opponent to accept.
32  */
33 
34 dble ()  {
35 	register int	resp;			/* response to y/n */
36 
37 	for (;;)  {
38 		writel (" doubles.");		/* indicate double */
39 
40 		if (cturn == -pnum)  {		/* see if computer accepts */
41 			if (dblgood())  {	    /* guess not */
42 				writel ("  Declined.\n");
43 				nexturn();
44 				cturn *= -2;	    /* indicate loss */
45 				return;
46 			} else  {		    /* computer accepts */
47 				writel ("  Accepted.\n");
48 				gvalue *= 2;	    /* double game value */
49 				dlast = cturn;
50 				if (tflag)
51 					gwrite();
52 				return;
53 			}
54 		}
55 
56 						/* ask if player accepts */
57 		writel ("  Does ");
58 		writel (cturn == 1? color[2]: color[3]);
59 		writel (" accept?");
60 
61 						/* get response from yorn,
62 						 * a "2" means he said "p"
63 						 * for print board. */
64 		if ((resp = yorn ('R')) == 2)  {
65 			writel ("  Reprint.\n");
66 			buflush();
67 			wrboard();
68 			writel (*Colorptr);
69 			continue;
70 		}
71 
72 						/* check response */
73 		if (resp)  {
74 						    /* accepted */
75 			gvalue *= 2;
76 			dlast = cturn;
77 			if (tflag)
78 				gwrite();
79 			return;
80 		}
81 
82 		nexturn ();			/* declined */
83 		cturn *= -2;
84 		return;
85 	}
86 }
87 
88 /*
89  * dblgood ()
90  *	Returns 1 if the computer would double in this position.  This
91  * is not an exact science.  The computer will decline a double that he
92  * would have made.  Accumulated judgments are kept in the variable n,
93  * which is in "pips", i.e., the position of each man summed over all
94  * men, with opponent's totals negative.  Thus, n should have a positive
95  * value of 7 for each move ahead, or a negative value of 7 for each one
96  * behind.
97  */
98 
99 dblgood ()  {
100 	register int	n;			/* accumulated judgment */
101 	register int	OFFC = *offptr;		/* no. of computer's men off */
102 	register int	OFFO = *offopp;		/* no. of player's men off */
103 
104 #ifdef DEBUG
105 	register int	i;
106 	if (trace == NULL)
107 		trace = fopen ("bgtrace","w");
108 #endif
109 
110 						/* get real pip value */
111 	n = eval()*cturn;
112 #ifdef DEBUG
113 	fputs ("\nDoubles:\nBoard: ",trace);
114 	for (i = 0; i < 26; i++)
115 		fprintf (trace," %d",board[i]);
116 	fprintf (trace,"\n\tpip = %d, ",n);
117 #endif
118 
119 						/* below adjusts pip value
120 						 * according to position
121 						 * judgments */
122 
123 						/* check men moving off
124 						 * board */
125 	if (OFFC > -15 || OFFO > -15)  {
126 		if (OFFC < 0 && OFFO < 0)  {
127 			OFFC += 15;
128 			OFFO += 15;
129 			n +=((OFFC-OFFO)*7)/2;
130 		} else if (OFFC < 0)  {
131 			OFFC += 15;
132 			n -= OFFO*7/2;
133 		} else if (OFFO < 0)  {
134 			OFFO += 15;
135 			n += OFFC*7/2;
136 		}
137 		if (OFFC < 8 && OFFO > 8)
138 			n -= 7;
139 		if (OFFC < 10 && OFFO > 10)
140 			n -= 7;
141 		if (OFFC < 12 && OFFO > 12)
142 			n -= 7;
143 		if (OFFO < 8 && OFFC > 8)
144 			n += 7;
145 		if (OFFO < 10 && OFFC > 10)
146 			n += 7;
147 		if (OFFO < 12 && OFFC > 12)
148 			n += 7;
149 		n += ((OFFC-OFFO)*7)/2;
150 	}
151 
152 #ifdef DEBUG
153 	fprintf (trace,"off = %d, ",n);
154 #endif
155 
156 						/* see if men are trapped */
157 	n -= freemen(bar);
158 	n += freemen(home);
159 	n += trapped(home,-cturn);
160 	n -= trapped(bar,cturn);
161 
162 #ifdef DEBUG
163 	fprintf (trace,"free = %d\n",n);
164 	fprintf (trace,"\tOFFC = %d, OFFO = %d\n",OFFC,OFFO);
165 	fflush (trace);
166 #endif
167 
168 						/* double if 2-3 moves ahead */
169 	if (n > 10+rnum(7))
170 		return(1);
171 	return (0);
172 }
173 
174 freemen (b)
175 int	b;
176 
177 {
178 	register int	i, inc, lim;
179 
180 	odds(0,0,0);
181 	if (board[b] == 0)
182 		return (0);
183 	inc = (b == 0? 1: -1);
184 	lim = (b == 0? 7: 18);
185 	for (i = b+inc; i != lim; i += inc)
186 		if (board[i]*inc < -1)
187 			odds(abs(b-i),0,abs(board[b]));
188 	if (abs(board[b]) == 1)
189 		return ((36-count())/5);
190 	return (count()/5);
191 }
192 
193 trapped (n,inc)
194 int	n, inc;
195 
196 {
197 	register int	i, j, k;
198 	int		c, l, ct;
199 
200 	ct = 0;
201 	l = n+7*inc;
202 	for (i = n+inc; i != l; i += inc)  {
203 		odds (0,0,0);
204 		c = abs(i-l);
205 		if (board[i]*inc > 0)  {
206 			for (j = c; j < 13; j++)
207 				if (board[i+inc*j]*inc < -1)  {
208 					if (j < 7)
209 						odds (j,0,1);
210 					for (k = 1; k < 7 && k < j; k++)
211 						if (j-k < 7)
212 							odds (k,j-k,1);
213 				}
214 			ct += abs(board[i])*(36-count());
215 		}
216 	}
217 	return (ct/5);
218 }
219 
220 eval ()  {
221 
222 	register int	i, j;
223 
224 	for (j = i = 0; i < 26; i++)
225 		j += (board[i] >= 0 ? i*board[i] : (25-i)*board[i]);
226 
227 	if (off[1] >= 0)
228 		j += 25*off[1];
229 	else
230 		j += 25*(off[1]+15);
231 
232 	if (off[0] >= 0)
233 		j -= 25*off[0];
234 	else
235 		j -= 25*(off[0]+15);
236 	return (j);
237 }
238