utilities - TMPFS - Pass tmpfs_args to mount()
[dragonfly.git] / games / backgammon / backgammon / extra.c
blob3a9f1d60419c2225a21dc8edf5019821876b026a
1 /*-
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
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. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
29 * @(#)extra.c 8.1 (Berkeley) 5/31/93
30 * $FreeBSD: src/games/backgammon/backgammon/extra.c,v 1.4 1999/11/30 03:48:22 billf Exp $
31 * $DragonFly: src/games/backgammon/backgammon/extra.c,v 1.3 2006/08/08 16:36:11 pavalos Exp $
34 #include "back.h"
36 #ifdef DEBUG
37 #include <stdio.h>
38 FILE *trace;
39 #endif
41 static int eval(void);
44 * dble()
45 * Have the current player double and ask opponent to accept.
48 void
49 dble(void)
51 int resp; /* response to y/n */
53 for (;;) {
54 writel(" doubles."); /* indicate double */
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;
71 /* ask if player accepts */
72 writel(" Does ");
73 writel(cturn == 1 ? color[2] : color[3]);
74 writel(" accept?");
76 /* get response from yorn, a "2" means he said "p" for print
77 * board. */
78 if ((resp = yorn('R')) == 2) {
79 writel(" Reprint.\n");
80 buflush();
81 wrboard();
82 writel(*Colorptr);
83 continue;
85 /* check response */
86 if (resp) {
87 /* accepted */
88 gvalue *= 2;
89 dlast = cturn;
90 if (tflag)
91 gwrite();
92 return;
94 nexturn(); /* declined */
95 cturn *= -2;
96 return;
101 * dblgood ()
102 * Returns 1 if the computer would double in this position. This
103 * is not an exact science. The computer will decline a double that he
104 * would have made. Accumulated judgments are kept in the variable n,
105 * which is in "pips", i.e., the position of each man summed over all
106 * men, with opponent's totals negative. Thus, n should have a positive
107 * value of 7 for each move ahead, or a negative value of 7 for each one
108 * behind.
112 dblgood(void)
114 int n; /* accumulated judgment */
115 int OFFC = *offptr; /* no. of computer's men off */
116 int OFFO = *offopp; /* no. of player's men off */
118 #ifdef DEBUG
119 int i;
120 if (trace == NULL)
121 trace = fopen("bgtrace", "w");
122 #endif
124 /* get real pip value */
125 n = eval() * cturn;
126 #ifdef DEBUG
127 fputs("\nDoubles:\nBoard: ", trace);
128 for (i = 0; i < 26; i++)
129 fprintf(trace, " %d", board[i]);
130 fprintf(trace, "\n\tpip = %d, ", n);
131 #endif
133 /* below adjusts pip value according to position judgments */
135 /* check men moving off board */
136 if (OFFC > -15 || OFFO > -15) {
137 if (OFFC < 0 && OFFO < 0) {
138 OFFC += 15;
139 OFFO += 15;
140 n += ((OFFC - OFFO) * 7) / 2;
141 } else
142 if (OFFC < 0) {
143 OFFC += 15;
144 n -= OFFO * 7 / 2;
145 } else
146 if (OFFO < 0) {
147 OFFO += 15;
148 n += OFFC * 7 / 2;
150 if (OFFC < 8 && OFFO > 8)
151 n -= 7;
152 if (OFFC < 10 && OFFO > 10)
153 n -= 7;
154 if (OFFC < 12 && OFFO > 12)
155 n -= 7;
156 if (OFFO < 8 && OFFC > 8)
157 n += 7;
158 if (OFFO < 10 && OFFC > 10)
159 n += 7;
160 if (OFFO < 12 && OFFC > 12)
161 n += 7;
162 n += ((OFFC - OFFO) * 7) / 2;
165 #ifdef DEBUG
166 fprintf(trace, "off = %d, ", n);
167 #endif
169 /* see if men are trapped */
170 n -= freemen(bar);
171 n += freemen(home);
172 n += trapped(home, -cturn);
173 n -= trapped(bar, cturn);
175 #ifdef DEBUG
176 fprintf(trace, "free = %d\n", n);
177 fprintf(trace, "\tOFFC = %d, OFFO = %d\n", OFFC, OFFO);
178 fflush(trace);
179 #endif
181 /* double if 2-3 moves ahead */
182 if (n > 10 + rnum(7))
183 return (1);
184 return (0);
188 freemen(int b)
190 int i, inc, lim;
192 odds(0, 0, 0);
193 if (board[b] == 0)
194 return (0);
195 inc = (b == 0 ? 1 : -1);
196 lim = (b == 0 ? 7 : 18);
197 for (i = b + inc; i != lim; i += inc)
198 if (board[i] * inc < -1)
199 odds(abs(b - i), 0, abs(board[b]));
200 if (abs(board[b]) == 1)
201 return ((36 - count()) / 5);
202 return (count() / 5);
206 trapped(int n, int inc)
208 int i, j, k;
209 int c, l, ct;
211 ct = 0;
212 l = n + 7 * inc;
213 for (i = n + inc; i != l; i += inc) {
214 odds(0, 0, 0);
215 c = abs(i - l);
216 if (board[i] * inc > 0) {
217 for (j = c; j < 13; j++)
218 if (board[i + inc * j] * inc < -1) {
219 if (j < 7)
220 odds(j, 0, 1);
221 for (k = 1; k < 7 && k < j; k++)
222 if (j - k < 7)
223 odds(k, j - k, 1);
225 ct += abs(board[i]) * (36 - count());
228 return (ct / 5);
231 static int
232 eval(void)
234 int i, j;
236 for (j = i = 0; i < 26; i++)
237 j += (board[i] >= 0 ? i * board[i] : (25 - i) * board[i]);
239 if (off[1] >= 0)
240 j += 25 * off[1];
241 else
242 j += 25 * (off[1] + 15);
244 if (off[0] >= 0)
245 j -= 25 * off[0];
246 else
247 j -= 25 * (off[0] + 15);
248 return (j);