/* tsumechk.c
 *	routines to test if an attacking piece is giving check
 *
 *	Routines named chk_'piece' test if the piece can take the 
 *	defenders king on its next move. 
 *		If yes then they return MATE else NULL.
 *
 *	Routines named chk_'direction' test is the defenders king
 *	is in the next square in that direction from the
 *	supplied coordinates.
 *		If yes then they return MATE else NULL.
 *
 */

#include "tsume.h"
#include "tsumedat.h"

int chk_pawn ( cur_x, cur_y )
int cur_x, cur_y;
{	return ( chk_dir_up ( cur_x, cur_y ) );
}


int chk_lance ( cur_x, cur_y )
int cur_x, cur_y;
{	int	t1;

	t1 = chk_dir_up ( cur_x, cur_y-- );
	while ( t1 == OPEN )	t1 = chk_dir_up ( cur_x, cur_y-- );

	return ( t1 );
}


int chk_horse ( cur_x, cur_y )
int cur_x, cur_y;
{	if ( cur_y-- <= 2 )	return ( NULL );

	if ( MATE == chk_dir_up_l ( cur_x, cur_y ) ||
	     MATE == chk_dir_up_r ( cur_x, cur_y ) )
		return ( MATE );
	else	return ( NULL );
}


int chk_silver ( cur_x, cur_y )
int cur_x, cur_y;
{	if ( chk_dir_up    ( cur_x, cur_y ) == MATE ||
	     chk_dir_up_l  ( cur_x, cur_y ) == MATE ||
	     chk_dir_up_r  ( cur_x, cur_y ) == MATE ||
	     chk_dir_dwn_l ( cur_x, cur_y ) == MATE ||
	     chk_dir_dwn_r ( cur_x, cur_y ) == MATE )
		return ( MATE );
	else	return ( NULL );
}


int chk_gold ( cur_x, cur_y )
int cur_x, cur_y;
{	if ( chk_dir_up    ( cur_x, cur_y ) == MATE ||
	     chk_dir_up_l  ( cur_x, cur_y ) == MATE ||
	     chk_dir_up_r  ( cur_x, cur_y ) == MATE ||
	     chk_dir_rig   ( cur_x, cur_y ) == MATE ||
	     chk_dir_lef   ( cur_x, cur_y ) == MATE ||
	     chk_dir_dwn   ( cur_x, cur_y ) == MATE )
		return ( MATE );
	else	return ( NULL );
}


int chk_rook ( cur_x, cur_y )
int cur_x, cur_y;
{	int	t1, t2, t3, t4, i_x, i_y;

	i_x = cur_x;
	i_y = cur_y;

	t1 = chk_dir_up ( cur_x, cur_y-- );
	while ( t1 == OPEN )	t1 = chk_dir_up ( cur_x, cur_y-- );
	if ( t1 == MATE )	return ( MATE );

	cur_x = i_x;
	cur_y = i_y;

	while ( ( t2 = chk_dir_lef ( cur_x++, cur_y ) ) == OPEN );
	if ( t2 == MATE )	return ( MATE );

	cur_x = i_x;
	cur_y = i_y;

	while ( ( t3 = chk_dir_rig ( cur_x--, cur_y ) ) == OPEN );
	if ( t3 == MATE )	return ( MATE );

	cur_x = i_x;
	cur_y = i_y;

	while ( ( t4 = chk_dir_dwn ( cur_x, cur_y++ ) ) == OPEN )
	if ( t4 == MATE )	return ( MATE );

	return ( NULL );
}


int chk_bishop ( cur_x, cur_y )
int cur_x, cur_y;
{	int	t1, t2, t3, t4, i_x, i_y;

	i_x = cur_x;	i_y = cur_y;

	t1 = chk_dir_up_l ( cur_x++, cur_y-- );
	while ( t1 == OPEN )	t1 = chk_dir_up_l ( cur_x++, cur_y-- );
	if ( t1 == MATE )	return ( MATE );

	cur_x = i_x;	cur_y = i_y;

	while ( ( t2 = chk_dir_dwn_l ( cur_x++, cur_y++ ) ) == OPEN );
	if ( t2 == MATE )	return ( MATE );

	cur_x = i_x;	cur_y = i_y;

	while ( ( t3 = chk_dir_up_r ( cur_x--, cur_y-- ) ) == OPEN );
	if ( t3 == MATE )	return ( MATE );

	cur_x = i_x;	cur_y = i_y;

	while ( ( t4 = chk_dir_dwn_r ( cur_x--, cur_y++ ) ) == OPEN );
	if ( t4 == MATE )	return ( MATE );

	return ( NULL );
}


int chk_p_rook ( cur_x, cur_y )
int cur_x, cur_y;
{	int	t1, t2, t3, t4, i_x, i_y;

	i_x = cur_x;	i_y = cur_y;

	t1 = chk_dir_up ( cur_x, cur_y-- );
	while ( t1 == OPEN )	t1 = chk_dir_up ( cur_x, cur_y-- );
	if ( t1 == MATE )	return ( MATE );

	cur_x = i_x;	cur_y = i_y;

	while ( ( t2 = chk_dir_lef ( cur_x++, cur_y ) ) == OPEN );
	if ( t2 == MATE )	return ( MATE );

	cur_x = i_x;	cur_y = i_y;

	while ( ( t3 = chk_dir_rig ( cur_x--, cur_y ) ) == OPEN );
	if ( t3 == MATE )	return ( MATE );

	cur_x = i_x;	cur_y = i_y;

	t4 = chk_dir_dwn ( cur_x, cur_y++ );
	while ( t4 == OPEN )	t4 = chk_dir_dwn ( cur_x, cur_y++ );
	if ( t4 == MATE )	return ( MATE );

	cur_x = i_x;	cur_y = i_y;
	if ( chk_dir_up_r  ( cur_x, cur_y ) == MATE )	return MATE;
	if ( chk_dir_up_l  ( cur_x, cur_y ) == MATE )	return MATE;
	if ( chk_dir_dwn_r ( cur_x, cur_y ) == MATE )	return MATE;
	if ( chk_dir_dwn_l ( cur_x, cur_y ) == MATE )	return MATE;

	return ( NULL );
}


int chk_p_bishop ( cur_x, cur_y )
int cur_x, cur_y;
{	int	t1, t2, t3, t4, i_x, i_y;

	i_x = cur_x;	i_y = cur_y;

	t1 = chk_dir_up_l ( cur_x++, cur_y-- );
	while ( t1 == OPEN )	t1 = chk_dir_up_l ( cur_x++, cur_y-- );
	if ( t1 == MATE )	return ( MATE );

	cur_x = i_x;	cur_y = i_y;

	while ( ( t2 = chk_dir_dwn_l ( cur_x++, cur_y++ ) ) == OPEN );
	if ( t2 == MATE )	return ( MATE );

	cur_x = i_x;	cur_y = i_y;

	while ( ( t3 = chk_dir_up_r ( cur_x--, cur_y-- ) ) == OPEN );
	if ( t3 == MATE )	return ( MATE );

	cur_x = i_x;	cur_y = i_y;

	while ( ( t4 = chk_dir_dwn_r ( cur_x--, cur_y++ ) ) == OPEN );
	if ( t4 == MATE )	return ( MATE );

	cur_x = i_x;	cur_y = i_y;
	if ( chk_dir_up  ( cur_x, cur_y ) == MATE ||
	     chk_dir_lef ( cur_x, cur_y ) == MATE ||
	     chk_dir_rig ( cur_x, cur_y ) == MATE ||
	     chk_dir_dwn ( cur_x, cur_y ) == MATE )
		return ( MATE );
	else	return ( NULL );
}


int chk_dir_up ( cur_x, cur_y )
int cur_x, cur_y;
{	char target;

	if ( cur_x == 0 )	return ( NULL );
	if ( cur_y == 1 )	return ( NULL );
	target = curr_board [ cur_x + 9 * ( cur_y - 1 )];
	if ( target == DEF_KING )
				return ( MATE );
	if ( target == NULL )	return ( OPEN );
	else			return ( NULL );
}


int chk_dir_lef ( cur_x, cur_y )
int cur_x, cur_y;
{	char target;

	if ( cur_x == 0 )	return ( NULL );
	if ( cur_x == 9 )	return ( NULL );
	target = curr_board [ cur_x + 1 + 9 * cur_y ];
	if ( target == DEF_KING )
				return ( MATE );
	if ( target == NULL )	return ( OPEN );
	else			return ( NULL );
}


int chk_dir_rig ( cur_x, cur_y )
int cur_x, cur_y;
{	char target;

	if ( cur_x <= 1 )	return ( NULL );
	target = curr_board [ cur_x - 1 + 9 * cur_y ];
	if ( target == DEF_KING )
				return ( MATE );
	if ( target == NULL )	return ( OPEN );
	else			return ( NULL );
}


int chk_dir_dwn ( cur_x, cur_y )
int cur_x, cur_y;
{	char target;

	if ( cur_x == 0 )	return ( NULL );
	if ( cur_y == 9 )	return ( NULL );
	target = curr_board [ cur_x + 9 * ( cur_y + 1 ) ];
	if ( target == DEF_KING )
				return ( MATE );
	if ( target == NULL )	return ( OPEN );
	else			return ( NULL );
}


int chk_dir_dwn_r ( cur_x, cur_y )
int cur_x, cur_y;
{	char target;

	if ( cur_x == 0 )	return ( NULL );
	if ( cur_x == 1 )	return ( NULL );
	if ( cur_y == 9 )	return ( NULL );
	target = curr_board [ cur_x - 1 + 9 * ( cur_y + 1 ) ];
	if ( target == DEF_KING )
				return ( MATE );
	if ( target == NULL )	return ( OPEN );
	else			return ( NULL );
}


int chk_dir_dwn_l ( cur_x, cur_y )
int cur_x, cur_y;
{	char target;

	if ( cur_x == 0 )	return ( NULL );
	if ( cur_x == 9 )	return ( NULL );
	if ( cur_y == 9 )	return ( NULL );
	target = curr_board [ cur_x + 1 + 9 * ( cur_y + 1 ) ];
	if ( target == DEF_KING )
				return ( MATE );
	if ( target == NULL )	return ( OPEN );
	else			return ( NULL );
}


int chk_dir_up_l ( cur_x, cur_y )
int cur_x, cur_y;
{	char target;

	if ( cur_x == 9 )	return ( NULL );
	if ( cur_y <= 1 )	return ( NULL );
	target = curr_board [ cur_x + 1 + 9 * ( cur_y - 1 ) ];
	if ( cur_x == 0 )	return ( NULL );
	if ( target == DEF_KING )
				return ( MATE );
	if ( target == NULL )	return ( OPEN );
	else			return ( NULL );
}


int chk_dir_up_r ( cur_x, cur_y )
int cur_x, cur_y;
{	char target;

	if ( cur_x <= 1 )	return ( NULL );
	if ( cur_y <= 1 )	return ( NULL );
	target = curr_board [ cur_x - 1 + 9 * ( cur_y - 1 ) ];
	if ( target == DEF_KING )
				return ( MATE );
	if ( target == NULL )	return ( OPEN );
	else			return ( NULL );
}
