-WARNS6 cleanup (1858 warnings)
[dragonfly.git] / games / backgammon / backgammon / extra.c
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 }