Home | History | Annotate | Line # | Download | only in backgammon
      1 /*	$NetBSD: extra.c,v 1.7 2009/08/12 05:17:57 dholland Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1980, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. Neither the name of the University nor the names of its contributors
     16  *    may be used to endorse or promote products derived from this software
     17  *    without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 #ifndef lint
     34 #if 0
     35 static char sccsid[] = "@(#)extra.c	8.1 (Berkeley) 5/31/93";
     36 #else
     37 __RCSID("$NetBSD: extra.c,v 1.7 2009/08/12 05:17:57 dholland Exp $");
     38 #endif
     39 #endif /* not lint */
     40 
     41 #include "back.h"
     42 #include "backlocal.h"
     43 
     44 #ifdef DEBUG
     45 FILE   *trace;
     46 #endif
     47 
     48 static int eval(void);
     49 
     50 /*
     51  * dble()
     52  *	Have the current player double and ask opponent to accept.
     53  */
     54 
     55 void
     56 dble(void)
     57 {
     58 	int     resp;		/* response to y/n */
     59 
     60 	for (;;) {
     61 		writel(" doubles.");	/* indicate double */
     62 
     63 		if (cturn == -pnum) {	/* see if computer accepts */
     64 			if (dblgood()) {	/* guess not */
     65 				writel("  Declined.\n");
     66 				nexturn();
     67 				cturn *= -2;	/* indicate loss */
     68 				return;
     69 			} else {/* computer accepts */
     70 				writel("  Accepted.\n");
     71 				gvalue *= 2;	/* double game value */
     72 				dlast = cturn;
     73 				if (tflag)
     74 					gwrite();
     75 				return;
     76 			}
     77 		}
     78 		/* ask if player accepts */
     79 		writel("  Does ");
     80 		writel(cturn == 1 ? color[2] : color[3]);
     81 		writel(" accept?");
     82 
     83 		/* get response from yorn, a "2" means he said "p" for print
     84 		 * board. */
     85 		if ((resp = yorn('R')) == 2) {
     86 			writel("  Reprint.\n");
     87 			buflush();
     88 			wrboard();
     89 			writel(*Colorptr);
     90 			continue;
     91 		}
     92 		/* check response */
     93 		if (resp) {
     94 			/* accepted */
     95 			gvalue *= 2;
     96 			dlast = cturn;
     97 			if (tflag)
     98 				gwrite();
     99 			return;
    100 		}
    101 		nexturn();	/* declined */
    102 		cturn *= -2;
    103 		return;
    104 	}
    105 }
    106 /*
    107  * dblgood ()
    108  *	Returns 1 if the computer would double in this position.  This
    109  * is not an exact science.  The computer will decline a double that he
    110  * would have made.  Accumulated judgments are kept in the variable n,
    111  * which is in "pips", i.e., the position of each man summed over all
    112  * men, with opponent's totals negative.  Thus, n should have a positive
    113  * value of 7 for each move ahead, or a negative value of 7 for each one
    114  * behind.
    115  */
    116 
    117 int
    118 dblgood(void)
    119 {
    120 	int     n;		/* accumulated judgment */
    121 	int     OFFC = *offptr;	/* no. of computer's men off */
    122 	int     OFFO = *offopp;	/* no. of player's men off */
    123 
    124 #ifdef DEBUG
    125 	int     i;
    126 	if (trace == NULL)
    127 		trace = fopen("bgtrace", "w");
    128 #endif
    129 
    130 	/* get real pip value */
    131 	n = eval() * cturn;
    132 #ifdef DEBUG
    133 	fputs("\nDoubles:\nBoard: ", trace);
    134 	for (i = 0; i < 26; i++)
    135 		fprintf(trace, " %d", board[i]);
    136 	fprintf(trace, "\n\tpip = %d, ", n);
    137 #endif
    138 
    139 	/* below adjusts pip value according to position judgments */
    140 
    141 	/* check men moving off board */
    142 	if (OFFC > -15 || OFFO > -15) {
    143 		if (OFFC < 0 && OFFO < 0) {
    144 			OFFC += 15;
    145 			OFFO += 15;
    146 			n += ((OFFC - OFFO) * 7) / 2;
    147 		} else
    148 			if (OFFC < 0) {
    149 				OFFC += 15;
    150 				n -= OFFO * 7 / 2;
    151 			} else
    152 				if (OFFO < 0) {
    153 					OFFO += 15;
    154 					n += OFFC * 7 / 2;
    155 				}
    156 		if (OFFC < 8 && OFFO > 8)
    157 			n -= 7;
    158 		if (OFFC < 10 && OFFO > 10)
    159 			n -= 7;
    160 		if (OFFC < 12 && OFFO > 12)
    161 			n -= 7;
    162 		if (OFFO < 8 && OFFC > 8)
    163 			n += 7;
    164 		if (OFFO < 10 && OFFC > 10)
    165 			n += 7;
    166 		if (OFFO < 12 && OFFC > 12)
    167 			n += 7;
    168 		n += ((OFFC - OFFO) * 7) / 2;
    169 	}
    170 #ifdef DEBUG
    171 	fprintf(trace, "off = %d, ", n);
    172 #endif
    173 
    174 	/* see if men are trapped */
    175 	n -= freemen(bar);
    176 	n += freemen(home);
    177 	n += trapped(home, -cturn);
    178 	n -= trapped(bar, cturn);
    179 
    180 #ifdef DEBUG
    181 	fprintf(trace, "free = %d\n", n);
    182 	fprintf(trace, "\tOFFC = %d, OFFO = %d\n", OFFC, OFFO);
    183 	fflush(trace);
    184 #endif
    185 
    186 	/* double if 2-3 moves ahead */
    187 	if (n > 10 + rnum(7))
    188 		return (1);
    189 	return (0);
    190 }
    191 
    192 int
    193 freemen(int b)
    194 {
    195 	int     i, inc, lim;
    196 
    197 	odds(0, 0, 0);
    198 	if (board[b] == 0)
    199 		return (0);
    200 	inc = (b == 0 ? 1 : -1);
    201 	lim = (b == 0 ? 7 : 18);
    202 	for (i = b + inc; i != lim; i += inc)
    203 		if (board[i] * inc < -1)
    204 			odds(abs(b - i), 0, abs(board[b]));
    205 	if (abs(board[b]) == 1)
    206 		return ((36 - count()) / 5);
    207 	return (count() / 5);
    208 }
    209 
    210 int
    211 trapped(int n, int inc)
    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 static int
    237 eval(void)
    238 {
    239 	int     i, j;
    240 
    241 	for (j = i = 0; i < 26; i++)
    242 		j += (board[i] >= 0 ? i * board[i] : (25 - i) * board[i]);
    243 
    244 	if (off[1] >= 0)
    245 		j += 25 * off[1];
    246 	else
    247 		j += 25 * (off[1] + 15);
    248 
    249 	if (off[0] >= 0)
    250 		j -= 25 * off[0];
    251 	else
    252 		j -= 25 * (off[0] + 15);
    253 	return (j);
    254 }
    255