* Copyright (c) 1980 Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)move.c 5.6 (Berkeley) 6/1/90";
struct BOARD
{ /* structure of game position */
int b_board
[26]; /* board position */
int b_in
[2]; /* men in */
int b_off
[2]; /* men off */
int b_st
[4], b_fn
[4]; /* moves */
struct BOARD
*b_next
; /* forward queue pointer */
struct BOARD
*checkq
= 0;
struct BOARD
*nextfree();
/* these variables are values for the
static int ch
; /* chance of being hit */
static int op
; /* computer's open men */
static int pt
; /* comp's protected points */
static int em
; /* farthest man back */
static int frc
; /* chance to free comp's men */
static int frp
; /* chance to free pl's men */
/* these values are the values for the
* move chosen (so far) */
static int chance
; /* chance of being hit */
static int openmen
; /* computer's open men */
static int points
; /* comp's protected points */
static int endman
; /* farthest man back */
static int barmen
; /* men on bar */
static int menin
; /* men in inner table */
static int menoff
; /* men off board */
static int oldfrc
; /* chance to free comp's men */
static int oldfrp
; /* chance to free pl's men */
static int cp
[5]; /* candidate start position */
static int cg
[5]; /* candidate finish position */
static int race
; /* game reduced to a race */
int okay
; /* zero if first move */
register int i
; /* index */
register int l
; /* last man */
/* see if comp should double */
if (gvalue
< 64 && dlast
!= cturn
&& dblgood()) {
if (cturn
!= 1 && cturn
!= -1)
for (i
= 0; i
< 26; i
++) {
for (i
= 0; i
< l
; i
++) {
curmove (cturn
== -1? 18: 19,0);
/* make tty interruptable
/* find out how many moves */
writel (" but cannot use it.\n");
for (i
= 0; i
< mvlim
; i
++) {
for (i
= 0; i
< mvlim
; i
++)
/* get ready for next move */
fixtty (raw
); /* no more tty interrupt */
register int mvnum
; /* number of move (rel zero) */
int swapped
; /* see if swapped also tested */
register int pos
; /* position on board */
register int rval
; /* value of roll */
/* if recursed through all dice
* values, compare move */
/* make sure dice in always
/* choose value for this move */
/* find all legitimate moves */
for (pos
= bar
; pos
!= home
; pos
+= cturn
) {
/* break if stuck on bar */
if (board
[bar
] != 0 && pos
!= bar
)
/* on to next if not occupied */
if (board
[pos
]*cturn
<= 0)
/* set up arrays for move */
g
[mvnum
] = pos
+rval
*cturn
;
if (g
[mvnum
]*cturn
>= home
) {
/* undo move to try another */
/* swap dice and try again */
if ((!swapped
) && D0
!= D1
)
register int i
; /* index */
struct BOARD
*now
; /* current position */
now
= nextfree (); /* get free BOARD */
now
->b_board
[i
] = board
[i
];
for (i
= 0; i
< mvlim
; i
++) {
struct BOARD
*new; /* item to insert */
register struct BOARD
*p
= checkq
; /* queue pointer */
register int result
; /* comparison result */
if (p
== 0) { /* check if queue empty */
result
= bcomp (new,p
); /* compare to first element */
if (result
< 0) { /* insert in front */
if (result
== 0) { /* duplicate entry */
while (p
->b_next
!= 0) { /* traverse queue */
result
= bcomp (new,p
->b_next
);
if (result
< 0) { /* found place */
if (result
== 0) { /* duplicate entry */
/* place at end of queue */
register int *aloc
= a
->b_board
; /* pointer to board a */
register int *bloc
= b
->b_board
; /* pointer to board b */
register int i
; /* index */
int result
; /* comparison result */
for (i
= 0; i
< 26; i
++) { /* compare boards */
result
= cturn
*(aloc
[i
]-bloc
[i
]);
return (result
); /* found inequality */
return (0); /* same position */
mvcheck (incumbent
,candidate
)
register struct BOARD
*incumbent
;
register struct BOARD
*candidate
;
for (i
= 0; i
< mvlim
; i
++) {
result
= cturn
*(candidate
->b_st
[i
]-incumbent
->b_st
[i
]);
for (i
= 0; i
< mvlim
; i
++) {
incumbent
->b_st
[i
] = candidate
->b_st
[i
];
incumbent
->b_fn
[i
] = candidate
->b_fn
[i
];
struct BOARD
*dead
; /* dead position */
dead
->b_next
= freeq
; /* add to freeq */
new = (struct BOARD
*)calloc (1,sizeof (struct BOARD
));
writel ("\nOut of memory\n");
/* current game position */
register struct BOARD
*now
= bsave();
register struct BOARD
*next
; /* next move */
trace
= fopen ("bgtrace","w");
fprintf (trace
,"\nRoll: %d %d%s\n",D0
,D1
,race
? " (race)": "");
register struct BOARD
*s
; /* game situation */
register int i
; /* index */
board
[i
] = s
->b_board
[i
];
for (i
= 0; i
< 2; i
++) {
for (i
= 0; i
< mvlim
; i
++) {
trace
= fopen ("bgtrace","w");
for (i
= 1; i
< 25; i
++) {
for (i
= bar
+cturn
; i
!= home
; i
+= cturn
)
frc
= freemen (bar
)+trapped (bar
,cturn
);
frp
= freemen (home
)+trapped (home
,-cturn
);
for (em
= bar
; em
!= home
; em
+= cturn
)
fprintf (trace
, " %d",board
[i
]);
fprintf (trace
,"\n\tem = %d\n",em
);
"\n\tch = %d, pt = %d, em = %d, frc = %d, frp = %d\n",
fputs ("\tMove: ",trace
);
for (i
= 0; i
< mvlim
; i
++)
fprintf (trace
," %d-%d",p
[i
],g
[i
]);
if ((cp
[0] == 0 && cg
[0] == 0) || movegood()) {
fprintf (trace
,"\t[%s] ... wins.\n",tests
);
for (i
= 0; i
< mvlim
; i
++) {
barmen
= abs(board
[home
]);
fprintf (trace
,"\t[%s] ... loses.\n",tests
);
return (*offptr
> menoff
);
n
= barmen
-abs(board
[home
]);
if (abs(chance
-ch
)+25*n
> rnum(150))
return (n
? (n
< 0): (ch
< chance
));
return (*offptr
> menoff
);
if (abs(openmen
-op
) > 7+rnum(12))
if (abs(endman
-em
) > rnum(2))
if (abs(frc
-oldfrc
) > rnum(2))
if (abs(n
= pt
-points
) > rnum(4))
if (abs(frp
-oldfrp
) > rnum(2))