/*P*/
/****************************************************************/
/*								*/
/* move piece							*/
/*								*/
/* Move_piece takes care of decrementing and incrementing the	*/
/* board array, and calling a function to display changes in	*/
/* the playing status. There are some checks made to see if	*/
/* source and destination are within range - these need to be	*/
/* here, and they're not a bug trap or anything. We can move	*/
/* pieces FROM an "out-of-range" source when we initialize the	*/
/* playing surface. We can move pieces TO an out-of-range dest	*/
/* when we take them off the board at the end (23/5 move, as	*/
/* an example for black).					*/
/*								*/
/****************************************************************/

#include	<stdio.h>
#include	"bkg.h"

#define		BLINK		0x80

move_piece( old_psn, new_psn, who, side )

int	old_psn, new_psn, who, side;

	{

	char	name[ 2 ], color[ 2 ];

#ifdef	KAYPRO

	name[ 0 ] = 'W';
	name[ 1 ] = 'B';

#endif

#ifdef	IBMPC

	name[ 0 ] = 0x02;	/* white */
	name[ 1 ] = 0x01;	/* black */

	color[ 0 ] = 0x07;	/* white */
	color[ 1 ] = 0x06;	/* black */

#endif

#ifdef	VAX

	name[ 0 ] = 'W';
	name[ 1 ] = 'B';

#endif

	move_it( old_psn, who, ' ', 0x00, side );

	/* move them puppies!	*/

	if ( ( old_psn >= 0  ) &&
	     ( old_psn <= 25 ) )
		board[ old_psn ][ who ]--;

	if ( ( ( who == BLACK  ) &&
	       ( new_psn < 25  ) ) ||
	     ( ( who == WHITE  ) &&
	       ( new_psn > 0   ) ) )
		board[ new_psn ][ who ]++;

	move_it( new_psn, who, name[ who ], color[ who ], side );

	} /* move piece */

/*P*/
/****************************************************************/
/*								*/
/* move_it							*/
/*								*/
/* This is the function to actually place a piece on the board.	*/
/* We divide the board into quadrants in this function, from 1	*/
/* being white's inner table, to 4 being black's inner table.	*/
/* Quadrants 0 and 5 are the bar. If we view the board from	*/
/* white's vantage point, the values of the point are reversed	*/
/* before calculating the quadrant. The variable "old_psn" is	*/
/* not aptly named in all cases; it is the point at which data	*/
/* are written, and this can be a blank for removing data, or	*/
/* a black/white man for adding data. Lastly, note that on the	*/
/* main points, we can fit 15 min in 3 cols of 5. On the bar,	*/
/* we can fit 3 rows of 3. So we scale the row/col number to	*/
/* write the data at the correct spot on the display.		*/
/*								*/
/****************************************************************/

move_it( old_psn, who, data, color, side )

int	old_psn, who;
char	data;
int	color;
int	side;

	{

	int	quad, x, y, disp;
	int	test, limit;
	
	/* if the old position is in range,	*/
	/* move the piece there.		*/

	if ( ( ( who == WHITE  ) &&
	       ( old_psn > 0   ) &&
	       ( old_psn <= 25 ) ) ||
	     ( ( who == BLACK  ) &&
	       ( old_psn >= 0  ) &&
	       ( old_psn < 25  ) ) )
		{

		test = old_psn;
		limit = 5;

		if ( side )
			{

			if ( old_psn == 25 )
				old_psn = 0;
			else
				if ( old_psn == 0 )
					old_psn = 25;
				else
					if ( old_psn < 13 )
						old_psn = old_psn + 12;
					else
						old_psn = old_psn - 12;

			} /* white side */

		/* Which quadrant are we in?	*/
		/* The bar's are different.	*/

		if ( old_psn == 0 )
			quad = 4;
		else
			if ( old_psn == 25 )
				quad = 5;
			else
				quad = ( old_psn - 1 ) / 6;

		switch( quad )
			{

			case 0:		/* white's inner table */
					x = 2;
					y = ( old_psn * 4 ) - 1;
					break;

			case 1:		/* white's outer table */
					x = 2;
					y = ( old_psn * 4 ) + 7;
					break;

			case 2:		/* black's outer table */
					x = 14;
					y = ( ( 25 - old_psn ) * 4 ) + 7;
					break;

			case 3:		/* black's inner table */
					x = 14;
					y = ( ( 25 - old_psn ) * 4 ) - 1;
					break;

			case 4:		/* black's bar */
					x = 5;
					y = 29;
					limit = 2;
					color |= BLINK;
					break;

			case 5:		/* white's bar */
					x = 11;
					y = 29;
					limit = 2;
					color |= BLINK;
					break;

			default:	printf( "move_piece: logic error #1: %d\n", quad );
					exit();
					break;

			} /* switch */

		/* Only actually place the piece if	*/
		/* there is room for it. This is 15 on	*/
		/* a point (so we are guaranteed) but	*/
		/* only 9 on the bar.			*/

		if ( board[ test ][ who ] <= ( limit * 3 ) )
			{

			/* offset the column by 1 either way	*/
			/* according to the # of pieces there.	*/

			if ( board[ test ][ who ] > limit )
				if ( board[ old_psn ][ who ] > ( limit * 2 ) )
					y++;
				else
					y--;

			/* offset the row according to the #	*/
			/* of pieces mod 5 that are there.	*/

			disp = board[ test ][ who ];
			while( disp > limit )
				disp -= limit;

			if ( ( quad < 2  ) ||
			     ( quad == 4 ) )
				x += disp - 1;
			else
				x -= disp - 1;

			if ( debug > 3 )
				{
				char_at( x, y, '+', 0x01 );
				raw_keyboard();
				}

			char_at( x, y, data, color );

			} /* within 15 or 9 */

		} /* old psn in range */

	} /* move_it */
