BSD 4_4 release
[unix-history] / usr / src / games / backgammon / backgammon / extra.c
CommitLineData
e0bbfbf9 1/*
7809477f
KB
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
69fb7db6 4 *
ad787160
C
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.
e0bbfbf9
DF
32 */
33
34#ifndef lint
ad787160 35static char sccsid[] = "@(#)extra.c 8.1 (Berkeley) 5/31/93";
69fb7db6 36#endif /* not lint */
90b39bb3
RH
37
38#include "back.h"
39
40#ifdef DEBUG
41#include <stdio.h>
42FILE *trace;
43#endif
44
45/*
46 * dble()
47 * Have the current player double and ask opponent to accept.
48 */
49
50dble () {
51 register 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\f
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
115dblgood () {
116 register int n; /* accumulated judgment */
117 register int OFFC = *offptr; /* no. of computer's men off */
118 register int OFFO = *offopp; /* no. of player's men off */
119
120#ifdef DEBUG
121 register 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\f
190freemen (b)
191int b;
192
193{
194 register 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\f
209trapped (n,inc)
210int n, inc;
211
212{
213 register 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\f
236eval () {
237
238 register 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}