VALID.CPP

/* -------------------------------------------------------------------------- 
b - board on which to make the move (will be changed on return)
t - RED, BLACK

returns 0 if invalid move
2 if continuable
else 1
-------------------------------------------------------------------------- */
int MoveValid(BOARD b, int start, int dest, int t)
{
int j; /* the piece we are jumping over */
int restore_depth;
int must_jump=0;

AssertSz(start > 0 && start <= 32, "ducks");
AssertSz(dest > 0 && dest <= 32, "geese");
AssertSz(t==RED || t==BLACK, "The Tetonkaha Wildabeast");
AssertSz(b[start], "it means buffalo");

/* destination empty */
if (0 != b[dest]) return 0;
pdebug(stddbgmin,"MoveValid destination empty %s(%d)",__FILE__,__LINE__);

/* if must jump rule is on */
if (rConfig.iMustJump)
{
int besttype, bestnumber;
long bestquality;
long c=-1; long p=-1; int fBreak=0;
int i=0;

restore_depth = depth_maximum;
depth_maximum = 1;
for (i=0;i<SQRS_MAX;i++)
{
if (b[i] & t)
{
must_jump += IterateJumps(b,i,t,0,
&besttype, &bestnumber, &bestquality,
c,p,&fBreak);
}
AssertSz(fBreak==0,"no way samual jones");
}
depth_maximum = restore_depth;
}

if (t == RED || (b[start] & KING))
{
pdebug(stddbgmin,"MoveValid considering RED moves %s(%d)",__FILE__,__LINE__);
if (red_lut[start][0] == dest) goto slide;
if (red_lut[start][2] == dest) goto slide;
if (red_jump_lut[start][1] == dest && (b[red_jump_lut[start][0]]|KING) == (next(t)|KING)) {j=red_jump_lut[start][0]; goto jump;}
if (red_jump_lut[start][3] == dest && (b[red_jump_lut[start][2]]|KING) == (next(t)|KING)) {j=red_jump_lut[start][2]; goto jump;}
}
if (t == BLACK || (b[start] & KING))
{
pdebug(stddbgmin,"MoveValid considering BLACK moves %s(%d)",__FILE__,__LINE__);
if (black_lut[start][0] == dest) goto slide;
if (black_lut[start][2] == dest) goto slide;
if (black_jump_lut[start][1] == dest && (b[black_jump_lut[start][0]]|KING) == (next(t)|KING)) {j=black_jump_lut[start][0]; goto jump;}
if (black_jump_lut[start][3] == dest && (b[black_jump_lut[start][2]]|KING) == (next(t)|KING)) {j=black_jump_lut[start][2]; goto jump;}
}

/* illegal position */
pdebug(stddbgmin,"MoveValid illegal position %s(%d)",__FILE__,__LINE__);
return 0;

slide:
pdebug(stddbgmin,"MoveValid found legal sliding move %s(%d)",__FILE__,__LINE__);
if (must_jump)
{
pdebug(stddbgmin,"slide attempt when jumping move is possible %s(%d)",__FILE__,__LINE__);
return 0;
}
b[dest] = b[start];
b[start] = 0;

if (RED & b[1]) b[1] |= KING;
if (RED & b[2]) b[2] |= KING;
if (RED & b[3]) b[3] |= KING;
if (RED & b[4]) b[4] |= KING;
if (BLACK & b[32]) b[32] |= KING;
if (BLACK & b[31]) b[31] |= KING;
if (BLACK & b[30]) b[30] |= KING;
if (BLACK & b[29]) b[29] |= KING;

return 1;

jump:
pdebug(stddbgmin,"MoveValid found legal jump %s(%d)",__FILE__,__LINE__);
b[dest] = b[start];
b[start] = 0;
b[j] = 0;

if (t == BLACK || (b[dest] & KING))
{
if (b[black_jump_lut[dest][1]] == 0 && (b[black_jump_lut[dest][0]]|KING) == (next(t)|KING)) {return 2;}
if (b[black_jump_lut[dest][3]] == 0 && (b[black_jump_lut[dest][2]]|KING) == (next(t)|KING)) {return 2;}
}

if (t == RED || (b[dest] & KING))
{
if (b[red_jump_lut[dest][1]] == 0 && (b[red_jump_lut[dest][0]]|KING) == (next(t)|KING)) {return 2;}
if (b[red_jump_lut[dest][3]] == 0 && (b[red_jump_lut[dest][2]]|KING) == (next(t)|KING)) {return 2;}
}

pdebug(stddbgmin,"MoveValid found jump is NOT continuable %s(%d)",__FILE__,__LINE__);
return 1;
}

/* --------------------------------------------------------------------------
GameOver returns

GAME_{WON}|{PLAYABLE}|{DRAWN}
--------------------------------------------------------------------------- */
int GameOver(BOARD b, int t)
{
int restore_depth;
int besttype, bestnumber;
long bestquality;
long c=-1; long p=-1; int fBreak=0;
int i=0; // Piece I'm on.
int move_is_possible=0;

restore_depth = depth_maximum;
depth_maximum = 1;
for (i=0;i<SQRS_MAX;i++)
{
if (b[i] & t)
{
move_is_possible += IterateJumps(b,i,t,0,
&besttype, &bestnumber, &bestquality,
c,p,&fBreak);
move_is_possible += IterateMoves(b,i,t,0,
&besttype, &bestnumber, &bestquality,
c,p,&fBreak);
if (move_is_possible)
break;
}
AssertSz(fBreak==0,"no way sammy jones");
}
depth_maximum = restore_depth;

/* ----- make sure this isn't a drawn game ----- */
if (move_is_possible)
{
int i=rConfig.iMaxMoves;
int t=0;
SQUARE b[SQRS_MAX];

if (CMoves.GetFirstBoard(b,&t))
while (CMoves.GetNextBoard(b,&t))
i--;
AssertSz(i > -5, "vania lorelle");
if (i<0)
return GAME_DRAWN;
}

if (move_is_possible)
return(GAME_PLAYABLE);
else
return(GAME_WON);

}