home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume28
/
ldb
/
part01
/
move.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-15
|
5KB
|
148 lines
/* move.c 8/5/91
*
* Copyright 1991 Perry R. Ross
*
* Permission to use, copy, modify, and distribute this software and its
* documentation without fee is hereby granted, subject to the restrictions
* detailed in the README file, which is included here by reference.
* Any other use requires written permission from the author. This software
* is distributed "as is" without any warranty, including any implied
* warranties of merchantability or fitness for a particular purpose.
* The author shall not be liable for any damages resulting from the
* use of this software. By using this software, the user agrees
* to these terms.
*/
#include "ldb.h"
/*-----------------------------------------------------------------------
* apply -- apply a move to a board
*
* Apply applies a move to a board, detecting the following errors:
* RJ_NOROLL The mv struct did not contain a valid roll.
* RJ_ONBAR The move attempted to move from a point other than
* the bar when pieces are on the bar.
* RJ_NOOFF The move attempted to move pieces off before all
* pieces are in the inner table.
* RJ_NOPIECE The move attempted to take a piece from an empty point.
* RJ_NOTYOURS The move attempted to move the opponent's piece.
* RJ_OCC The move attempted to move to an occupied point.
* RJ_EXACT The move attempted to bear off a piece with a
* larger roll than necessary when that piece was
* not the outermost piece.
* If the move was legal, apply returns:
* MVOK if no blot was hit, or
* point number where the blot was before it was hit.
* Note that blot numbers are in the range [1-24], MVOK is 0, and
* the reject codes are negative. When the move is rejected,
* the board is unchanged. When a blot is hit, it is moved to the
* appropriate bar point automatically.
*
* If A_REDRAW is set in flags, apply redraws the relevant portions of
* the screen to reflect the move. If A_CHKONLY is set in flags, the
* move is checked but the board is not modified.
*-----------------------------------------------------------------------
*/
apply(g,who,mn,flags,dest)
struct game *g; /* game structure */
int who; /* 0 = opponent, 1 = me */
int mn; /* which element of mv array */
int flags; /* A_* */
int *dest; /* where to store destination point */
{
int i, j, blot;
int op, np;
int dir;
char clr;
struct mv *m;
register struct point *b = g->board;
dir = who ? g->mydir : g->opdir;
clr = who ? g->mycolor : g->opcolor;
blot = MVOK; /* no blot hit yet */
m = who ? &g->mvs[mn] : &g->opmvs[mn];
if (m->roll <= 0) /* sanity check */
return(RJ_NOROLL); /* reject move */
op = m->pt; /* starting point number */
if (op < 0) /* this roll is unused */
return(MVOK); /* and that's ok */
if ( (op == 0) || (op == 25) ) /* moving off bar */
op = BARPT(dir); /* use correct bar point */
else { /* not moving off bar */
j = BARPT(dir); /* make sure no pieces still on bar */
if (b[j].qty > 0)
return(RJ_ONBAR); /* can't move, pieces on bar */
}
np = op + m->roll*dir; /* move piece correct number of pts */
if ( (np <= 0) || (np >= 25) ) {
i = (dir > 0) ? 19 : 1;
j = (dir > 0) ? 24 : 6;
if (addpcs(b,clr,i,j)+b[OFFPT(dir)].qty < 15) /* all pcs not */
return(RJ_NOOFF); /* in inner table, can't move off */
if ( (np != 0) && (np != 25) ) {/* using bigger roll than needed */
i = (dir > 0) ? 19 : op+1; /* check for pcs on higher pts */
j = (dir > 0) ? op-1 : 6;
if (addpcs(b,clr,i,j) > 0) /* there are some */
return(RJ_EXACT); /* must use roll on them */
}
np = OFFPT(dir); /* this piece is moving off */
}
if (b[op].qty <= 0) /* no piece here to move */
return(RJ_NOPIECE);
if (b[op].color != clr) /* trying to move opponent's pieces? */
return(RJ_NOTYOURS);
if (b[np].qty == 0) /* moving to an empty point */
b[np].color = b[op].color; /* copy color */
if (b[np].color != b[op].color) { /* moving to occupied pt */
if (b[np].qty == 1) { /* whacked a blot */
blot = np; /* save point number for return */
if ( (flags & A_CHKONLY) == 0) {
b[np].qty = 0; /* bye bye */
j = BARPT(REV(dir)); /* send it to opponents bar */
b[j].color = b[np].color; /* copy color to bar pt */
b[j].qty++; /* bump counter */
if (flags & A_REDRAW) /* update screen */
FeDrawPoint(b,j,0,g->flags & F_INVERT);
b[np].color = b[op].color; /* my point now */
}
}
else
return(RJ_OCC); /* point is occupied */
}
if ( (flags & A_CHKONLY) == 0) {
b[op].qty--; /* take piece from old pt */
b[np].qty++; /* and put in on new pt */
if (flags & A_REDRAW) {
FeDrawPoint(b,op,0,g->flags & F_INVERT);/* update the screen */
FeDrawPoint(b,np,0,g->flags & F_INVERT);
}
}
if (dest != NULL) /* return new position */
*dest = np;
return(blot); /* succeeded, return MVOK or blot */
}
/*----------------------------------------------------------------------
* addpcs -- add the number of pieces in a range of points
*
* This function returns the number of pieces of a certain color
* that reside within a range of points.
*----------------------------------------------------------------------
*/
addpcs(b,clr,f,t)
board b;
char clr;
int f, t;
{
int i, q;
q = 0; /* quantity we have found so far */
for (i = f; i <= t; i++)
if (b[i].color == clr) /* found some */
q += b[i].qty; /* count them */
return(q); /* return quantity found */
}