/* Modification IDs	  */
/* JL  == Jon Lundy       */
/* DG  == David Gilliam   */
/* PLH == Paul L. Hammond */
#include "plateau.h"
 
extern struct square board[4][4];
extern struct piece pieces[24];
extern struct square stack;
extern int to_capture[10];
extern int captureno;
 
/*  Onboard functions  */
 
int onboard_verify();
void add_to_stack();
 
/*  Move functions  */
 
int init_sq_verify();
int final_sq_verify();
int pickup();
int drop_off();
int capture();
int moveable();
 
int init_sq_verify(gameptr,buffer,icptr,irptr,pptr)
struct gameinfo *gameptr;
char buffer[];
int *icptr,*irptr;
int *pptr;
{   if (parsesquare(buffer,icptr,irptr) == -1)
	return -1;
    *pptr = board[*icptr][*irptr].link;
    if (*pptr == 99)
    {   scroll();
	drawline("There are no pieces on that square!!");
	return -1;
    }
    else if (COLOR(*pptr) != gameptr->color)
	 {  scroll();
	    drawline("You can't move your opponent's pieces!!");
	    return -1;
	 }
 
    return 0;
}
 
int final_sq_verify(gameptr,buffer,icolumn,irow,fcptr,frptr,maxdist)
struct gameinfo *gameptr;
char buffer[];
int icolumn,irow;
int *fcptr,*frptr;
int maxdist;
{   enum weapons topside;
    int dist;
 
    if (parsesquare(buffer,fcptr,frptr) == -1)
	return -1;
    topside = pieces[stack.link].top;
 
    if ((COLOR(board[*fcptr][*frptr].link) == 1-(gameptr->color)) &&
	topside == blank)
	    return -1;
 
    if (*fcptr == icolumn && *frptr == irow)
	return 0;
 
    if (topside == orange)
	if (abs(*fcptr-icolumn) == 2)
 	{   if (abs(*frptr-irow) == 1)
		return 1;
	    else
		return -1;
	}
	else if (abs(*fcptr-icolumn) == 1)
	     {  if (abs(*frptr-irow) == 2)
		    return 1;
		else
		    return -1;
	     }
	     else
		return -1;
 
    if (topside != blue)
	if (*fcptr == icolumn)
	{   dist = (abs(*frptr-irow));
	    if (dist > maxdist)
		return -1;
	    else
		return dist;
	}
	else
	    if (*frptr == irow)
	    {   dist = (abs(*fcptr-icolumn));
		if (dist > maxdist)
		    return -1;
		else
		    return dist;
	    }
 
    if (topside != red)
	if (abs(*fcptr-icolumn) == abs(*frptr-irow))
	{   dist = (abs(*frptr-irow));
	    if (dist > maxdist)
		return -1;
	    else
		return dist;
	}
 
    return -1;
}
 
 
int capture(gameptr,column,row,move_so_far,number)
struct gameinfo *gameptr;
int column,row;
char move_so_far[80];
int number;
{   int i,lastlink;
    int previous_link;
    int num_to_be_captured=0;
    char tempstr[80];
 
    if (number == 0)
	return 0;
 
    lastlink = board[column][row].link;
    strcat(move_so_far,"*");
    if (board[column][row].stackheight < number)
	return -1;
#ifdef old
    for (i=0;i<number;i++)
    {	if (COLOR(lastlink) != 1-(gameptr->color))
	    return -1;
	lastlink = pieces[lastlink].link;
    }
    lastlink = board[column][row].link;
 
    for (i=0;i<number;i++)
    {   board[column][row].link = pieces[lastlink].link;
	board[column][row].stackheight--;
	pieces[lastlink].status = to_be_captured;
	to_capture[captureno++] = lastlink;
	lastlink = pieces[lastlink].link;
    }
#else
/* JL:  allow you to capture pieces that are pinned underneath pieces of yours
   that were pinned */
    for (i=0;(i<board[column][row].stackheight) && (num_to_be_captured<number)
                ;i++)
    {
       if (COLOR(lastlink) == 1-(gameptr->color))
         num_to_be_captured++;
	lastlink = pieces[lastlink].link;
    }
    if (num_to_be_captured != number)
      return -1;
    lastlink = board[column][row].link;
    previous_link = -1;
    num_to_be_captured = 0;
    for (i=0;(i<board[column][row].stackheight) && (num_to_be_captured<number)
                ;i++)
    {
       if (COLOR(lastlink) == 1-(gameptr->color))
       {
           to_capture[captureno++] = lastlink;
           num_to_be_captured++;
           pieces[lastlink].status = to_be_captured;
           if (previous_link == -1)
              board[column][row].link = pieces[lastlink].link;
           else
              pieces[previous_link].link = pieces[lastlink].link;
           lastlink = pieces[lastlink].link;
       }
       else
       {
           previous_link = lastlink;
           lastlink = pieces[lastlink].link;
       }
    } 
    board[column][row].stackheight -= num_to_be_captured;
      
#endif
    strcpy(tempstr,move_so_far);
    sprintf(move_so_far,"%s%d",tempstr,number);
 
 
    if (pieces[board[column][row].link].revealed == none)
	pieces[board[column][row].link].revealed = to_be_top;
 
    return 0;
}   
 
 
int pickup(gameptr,column,row,number)
struct gameinfo *gameptr;
int column,row,number;
{   int i,pieceno,lastlink;
 
    if (stack.stackheight == 0)
    {   stack.link = board[column][row].link;
	board[column][row].link = pieces[stack.link].link;
	pieces[stack.link].link = 99;
	board[column][row].stackheight--;
 	stack.stackheight++;
	number--;
    }
 
    lastlink = stack.link;
    while(pieces[lastlink].link != 99)
	lastlink = pieces[lastlink].link;
 
 
    for (i=0;i<number;i++)
    {	pieceno=board[column][row].link;
	if (pieceno==99 || COLOR(pieceno) != gameptr->color)
	{   drop_off(gameptr,column,row,i,1);
	    return -1;
	}
	pieces[lastlink].link = pieceno;
	lastlink = pieceno;
	board[column][row].link = pieces[pieceno].link;
	pieces[pieceno].link = 99;
	stack.stackheight++;
	board[column][row].stackheight--;
    }
    return 0;
}
 
int drop_off(gameptr,column,row,number,flag)
struct gameinfo *gameptr;
int column,row,number;
int flag;
{   int newstackheight,i;
    int lastlink,pieceno;
    int lastpiece;
 
    lastpiece = stack.link;
    while (pieces[lastpiece].link != 99)
	lastpiece = pieces[lastpiece].link;
 
    newstackheight = stack.stackheight-number;
 
    if (newstackheight < 0)
	return -1;
    if (newstackheight == 0 && flag == 0)
	return -1;
    
    if (newstackheight == 0)
    {	pieces[lastpiece].link = board[column][row].link;
	board[column][row].link = stack.link;
	board[column][row].stackheight += stack.stackheight;
	stack.stackheight = 0;
	stack.link = 99;
	return 0;
    }
 
    pieceno = stack.link;
    for (i=0;i<newstackheight;i++)
    {   lastlink = pieceno;
	pieceno = pieces[lastlink].link;
    }
 
    if (pieces[pieceno].top == blank &&
	COLOR(board[column][row].link) == 1-(gameptr->color) &&
	flag == 0)
	    return -1;
 
    pieces[lastpiece].link = board[column][row].link;
    board[column][row].link = pieceno;
    pieces[lastlink].link = 99;
    board[column][row].stackheight += number;
    stack.stackheight -= number;
 
    if (pieces[pieceno].revealed == none)
	pieces[pieceno].revealed = top;
    
    return 0;
}
 
int onboard_verify(gameptr,height,column,row)
struct gameinfo *gameptr;
int height,column,row;
{   int i,lastlink;
 
    if (height < 1 || height > (board[column][row].stackheight + 1))
	return -1;
    if (height == (board[column][row].stackheight + 1))
	return 0;
    lastlink = board[column][row].link;
    
    i = 1; /* PLH 12/17/92 */
    while (++i < height)
	lastlink = pieces[lastlink].link;
   
    if (COLOR(lastlink) == gameptr->color)
	return 0;
    lastlink = pieces[lastlink].link;
 
    if (COLOR(lastlink) == gameptr->color)
	return 0;
 
    return -1;
}
 
void add_to_stack(column,row,height,pieceno,known)
int column,row,height,pieceno;
enum info known;
{   int i=1,lastlink;
 
    lastlink = board[column][row].link;
 
    if (height == 1)
    {   board[column][row].link = pieceno;
	pieces[pieceno].link = lastlink;
    }
    else
    {   while (++i < height)
	    lastlink = pieces[lastlink].link;
 
	pieces[pieceno].link = pieces[lastlink].link;
	pieces[lastlink].link = pieceno;
    }
    pieces[pieceno].status = onboard;
    pieces[pieceno].revealed = known;
    (board[column][row].stackheight)++;
}
 
int moveable(tempgame,game)
struct gameinfo tempgame,game;
{   if (tempgame.moveno != game.moveno)
	return (0);
    switch(game.status)
    {   case 'b':
	case 'w':
	case 'x': return (0);
 
	case 'o':	
	case 'p': if ((game.moveno % 2) != game.color)
			return (0);
	default:  return (1);
    }
}
