예제 #1
0
static int is_valid_move( CHAR_DATA * ch, GAME_BOARD_DATA * board, int x, int y, int dx, int dy )
{
	if ( dx < 0 || dy < 0 || dx > 7 || dy > 7 )
		return MOVE_OFFBOARD;

	if ( board->board[x][y] == NO_PIECE )
		return MOVE_INVALID;

	if ( x == dx && y == dy )
		return MOVE_INVALID;

	if ( IS_WHITE( board->board[x][y] ) && !str_cmp( board->player1, ch->name ) )
		return MOVE_WRONGCOLOR;
	if ( IS_BLACK( board->board[x][y] ) && ( !str_cmp( board->player2, ch->name ) || !ch ) )
		return MOVE_WRONGCOLOR;

	switch ( board->board[x][y] )
	{
		case WHITE_PAWN:
		case BLACK_PAWN:
			if ( IS_WHITE( board->board[x][y] ) && dx == x + 2 && x == 1 && dy == y && board->board[dx][dy] == NO_PIECE && board->board[x + 1][dy] == NO_PIECE )
				return MOVE_OK;
			else if ( IS_BLACK( board->board[x][y] ) && dx == x - 2 && x == 6 && dy == y && board->board[dx][dy] == NO_PIECE && board->board[x - 1][dy] == NO_PIECE )
				return MOVE_OK;
			if ( IS_WHITE( board->board[x][y] ) && dx != x + 1 )
				return MOVE_INVALID;
			else if ( IS_BLACK( board->board[x][y] ) && dx != x - 1 )
				return MOVE_INVALID;
			if ( dy != y && dy != y - 1 && dy != y + 1 )
				return MOVE_INVALID;
			if ( dy == y )
			{
				if ( board->board[dx][dy] == NO_PIECE )
					return MOVE_OK;
				else if ( SAME_COLOR( x, y, dx, dy ) )
					return MOVE_SAMECOLOR;
				else
					return MOVE_BLOCKED;
			}
			else
			{
				if ( board->board[dx][dy] == NO_PIECE )
					return MOVE_INVALID;
				else if ( SAME_COLOR( x, y, dx, dy ) )
					return MOVE_SAMECOLOR;
				else if ( board->board[dx][dy] != BLACK_KING && board->board[dx][dy] != WHITE_KING )
					return MOVE_TAKEN;
				else
					return MOVE_INVALID;
			}
			break;
		case WHITE_ROOK:
		case BLACK_ROOK:
			{
				int cnt;

				if ( dx != x && dy != y )
					return MOVE_INVALID;

				if ( dx == x )
				{
					for ( cnt = y; cnt != dy; )
					{
						if ( cnt != y && board->board[x][cnt] != NO_PIECE )
							return MOVE_BLOCKED;
						if ( dy > y )
							cnt++;
						else
							cnt--;
					}
				}
				else if ( dy == y )
				{
					for ( cnt = x; cnt != dx; )
					{
						if ( cnt != x && board->board[cnt][y] != NO_PIECE )
							return MOVE_BLOCKED;
						if ( dx > x )
							cnt++;
						else
							cnt--;
					}
				}

				if ( board->board[dx][dy] == NO_PIECE )
					return MOVE_OK;

				if ( !SAME_COLOR( x, y, dx, dy ) )
					return MOVE_TAKEN;

				return MOVE_SAMECOLOR;
			}
			break;
		case WHITE_KNIGHT:
		case BLACK_KNIGHT:
			if ( ( dx == x - 2 && dy == y - 1 ) ||
				( dx == x - 2 && dy == y + 1 ) ||
				( dx == x - 1 && dy == y - 2 ) ||
				( dx == x - 1 && dy == y + 2 ) || ( dx == x + 1 && dy == y - 2 ) || ( dx == x + 1 && dy == y + 2 ) || ( dx == x + 2 && dy == y - 1 ) || ( dx == x + 2 && dy == y + 1 ) )
			{
				if ( board->board[dx][dy] == NO_PIECE )
					return MOVE_OK;
				if ( SAME_COLOR( x, y, dx, dy ) )
					return MOVE_SAMECOLOR;
				return MOVE_TAKEN;
			}
			return MOVE_INVALID;
			break;
		case WHITE_BISHOP:
		case BLACK_BISHOP:
			{
				int l, m, blocked = FALSE;

				if ( dx == x || dy == y )
					return MOVE_INVALID;

				l = x;
				m = y;

				while ( 1 )
				{
					if ( dx > x )
						l++;
					else
						l--;
					if ( dy > y )
						m++;
					else
						m--;
					if ( l > 7 || m > 7 || l < 0 || m < 0 )
						return MOVE_INVALID;
					if ( l == dx && m == dy )
						break;
					if ( board->board[l][m] != NO_PIECE )
						blocked = TRUE;
				}
				if ( l != dx || m != dy )
					return MOVE_INVALID;

				if ( blocked )
					return MOVE_BLOCKED;

				if ( board->board[dx][dy] == NO_PIECE )
					return MOVE_OK;

				if ( !SAME_COLOR( x, y, dx, dy ) )
					return MOVE_TAKEN;

				return MOVE_SAMECOLOR;
			}
			break;
		case WHITE_QUEEN:
		case BLACK_QUEEN:
			{
				int l, m, blocked = FALSE;

				l = x;
				m = y;

				while ( 1 )
				{
					if ( dx > x )
						l++;
					else if ( dx < x )
						l--;
					if ( dy > y )
						m++;
					else if ( dy < y )
						m--;
					if ( l > 7 || m > 7 || l < 0 || m < 0 )
						return MOVE_INVALID;
					if ( l == dx && m == dy )
						break;
					if ( board->board[l][m] != NO_PIECE )
						blocked = TRUE;
				}
				if ( l != dx || m != dy )
					return MOVE_INVALID;

				if ( blocked )
					return MOVE_BLOCKED;

				if ( board->board[dx][dy] == NO_PIECE )
					return MOVE_OK;

				if ( !SAME_COLOR( x, y, dx, dy ) )
					return MOVE_TAKEN;

				return MOVE_SAMECOLOR;
			}
			break;
		case WHITE_KING:
		case BLACK_KING:
			{
				int sp, sk;

				if ( dx > x + 1 || dx < x - 1 || dy > y + 1 || dy < y - 1 )
					return MOVE_INVALID;
				sk = board->board[x][y];
				sp = board->board[dx][dy];
				board->board[x][y] = sp;
				board->board[dx][dy] = sk;
				if ( king_in_check( board, sk ) )
				{
					board->board[x][y] = sk;
					board->board[dx][dy] = sp;
					return MOVE_CHECK;
				}
				board->board[x][y] = sk;
				board->board[dx][dy] = sp;
				if ( board->board[dx][dy] == NO_PIECE )
					return MOVE_OK;
				if ( SAME_COLOR( x, y, dx, dy ) )
					return MOVE_SAMECOLOR;
				return MOVE_TAKEN;
			}
			break;
		default:
			bug( "Invaild piece: %d", board->board[x][y] );
			return MOVE_INVALID;
	}

	if ( ( IS_WHITE( board->board[x][y] ) && IS_WHITE( board->board[dx][dy] ) ) || ( IS_BLACK( board->board[x][y] ) && IS_BLACK( board->board[dx][dy] ) ) )
		return MOVE_SAMECOLOR;

	return MOVE_OK;
}
예제 #2
0
static bool king_in_check( GAME_BOARD_DATA * board, int piece )
{
	int x = 0, y = 0, l, m;

	if ( piece != WHITE_KING && piece != BLACK_KING )
		return FALSE;

	if ( !find_piece( board, &x, &y, piece ) )
		return FALSE;

	if ( x < 0 || y < 0 || x > 7 || y > 7 )
		return FALSE;

	/*
	 * pawns 
	 */
	if ( IS_WHITE( piece ) && x < 7 && ( ( y > 0 && IS_BLACK( board->board[x + 1][y - 1] ) ) || ( y < 7 && IS_BLACK( board->board[x + 1][y + 1] ) ) ) )
		return TRUE;
	else if ( IS_BLACK( piece ) && x > 0 && ( ( y > 0 && IS_WHITE( board->board[x - 1][y - 1] ) ) || ( y < 7 && IS_WHITE( board->board[x - 1][y + 1] ) ) ) )
		return TRUE;
	/*
	 * knights 
	 */
	if ( x - 2 >= 0 && y - 1 >= 0 &&
		( ( board->board[x - 2][y - 1] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x - 2][y - 1] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) )
		return TRUE;
	if ( x - 2 >= 0 && y + 1 < 8 &&
		( ( board->board[x - 2][y + 1] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x - 2][y + 1] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) )
		return TRUE;

	if ( x - 1 >= 0 && y - 2 >= 0 &&
		( ( board->board[x - 1][y - 2] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x - 1][y - 2] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) )
		return TRUE;
	if ( x - 1 >= 0 && y + 2 < 8 &&
		( ( board->board[x - 1][y + 2] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x - 1][y + 2] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) )
		return TRUE;

	if ( x + 1 < 8 && y - 2 >= 0 &&
		( ( board->board[x + 1][y - 2] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x + 1][y - 2] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) )
		return TRUE;
	if ( x + 1 < 8 && y + 2 < 8 &&
		( ( board->board[x + 1][y + 2] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x + 1][y + 2] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) )
		return TRUE;

	if ( x + 2 < 8 && y - 1 >= 0 &&
		( ( board->board[x + 2][y - 1] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x + 2][y - 1] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) )
		return TRUE;
	if ( x + 2 < 8 && y + 1 < 8 &&
		( ( board->board[x + 2][y + 1] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x + 2][y + 1] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) )
		return TRUE;

	/*
	 * horizontal/vertical long distance 
	 */
	for ( l = x + 1; l < 8; l++ )
		if ( board->board[l][y] != NO_PIECE )
		{
			if ( SAME_COLOR( x, y, l, y ) )
				break;
			if ( board->board[l][y] == BLACK_QUEEN || board->board[l][y] == WHITE_QUEEN || board->board[l][y] == BLACK_ROOK || board->board[l][y] == WHITE_ROOK )
				return TRUE;
			break;
		}
	for ( l = x - 1; l >= 0; l-- )
		if ( board->board[l][y] != NO_PIECE )
		{
			if ( SAME_COLOR( x, y, l, y ) )
				break;
			if ( board->board[l][y] == BLACK_QUEEN || board->board[l][y] == WHITE_QUEEN || board->board[l][y] == BLACK_ROOK || board->board[l][y] == WHITE_ROOK )
				return TRUE;
			break;
		}
	for ( m = y + 1; m < 8; m++ )
		if ( board->board[x][m] != NO_PIECE )
		{
			if ( SAME_COLOR( x, y, x, m ) )
				break;
			if ( board->board[x][m] == BLACK_QUEEN || board->board[x][m] == WHITE_QUEEN || board->board[x][m] == BLACK_ROOK || board->board[x][m] == WHITE_ROOK )
				return TRUE;
			break;
		}
	for ( m = y - 1; m >= 0; m-- )
		if ( board->board[x][m] != NO_PIECE )
		{
			if ( SAME_COLOR( x, y, x, m ) )
				break;
			if ( board->board[x][m] == BLACK_QUEEN || board->board[x][m] == WHITE_QUEEN || board->board[x][m] == BLACK_ROOK || board->board[x][m] == WHITE_ROOK )
				return TRUE;
			break;
		}
	/*
	 * diagonal long distance 
	 */
	for ( l = x + 1, m = y + 1; l < 8 && m < 8; l++, m++ )
		if ( board->board[l][m] != NO_PIECE )
		{
			if ( SAME_COLOR( x, y, l, m ) )
				break;
			if ( board->board[l][m] == BLACK_QUEEN || board->board[l][m] == WHITE_QUEEN || board->board[l][m] == BLACK_BISHOP || board->board[l][m] == WHITE_BISHOP )
				return TRUE;
			break;
		}
	for ( l = x - 1, m = y + 1; l >= 0 && m < 8; l--, m++ )
		if ( board->board[l][m] != NO_PIECE )
		{
			if ( SAME_COLOR( x, y, l, m ) )
				break;
			if ( board->board[l][m] == BLACK_QUEEN || board->board[l][m] == WHITE_QUEEN || board->board[l][m] == BLACK_BISHOP || board->board[l][m] == WHITE_BISHOP )
				return TRUE;
			break;
		}
	for ( l = x + 1, m = y - 1; l < 8 && m >= 0; l++, m-- )
		if ( board->board[l][m] != NO_PIECE )
		{
			if ( SAME_COLOR( x, y, l, m ) )
				break;
			if ( board->board[l][m] == BLACK_QUEEN || board->board[l][m] == WHITE_QUEEN || board->board[l][m] == BLACK_BISHOP || board->board[l][m] == WHITE_BISHOP )
				return TRUE;
			break;
		}
	for ( l = x - 1, m = y - 1; l >= 0 && m >= 0; l--, m-- )
		if ( board->board[l][m] != NO_PIECE )
		{
			if ( SAME_COLOR( x, y, l, m ) )
				break;
			if ( board->board[l][m] == BLACK_QUEEN || board->board[l][m] == WHITE_QUEEN || board->board[l][m] == BLACK_BISHOP || board->board[l][m] == WHITE_BISHOP )
				return TRUE;
			break;
		}
	return FALSE;
}
예제 #3
0
파일: chess.cpp 프로젝트: xorith/AFKMud
int is_valid_move( char_data * ch, game_board_data * board, int x, int y, int dx, int dy )
{
    if( !ch )
    {
        bug( "%s: nullptr ch!", __func__ );
        return MOVE_INVALID;
    }

    if( !board )
    {
        bug( "%s: nullptr board!", __func__ );
        return MOVE_INVALID;
    }

    if( dx < 0 || dy < 0 || dx > 7 || dy > 7 )
        return MOVE_OFFBOARD;

    if( board->board[x][y] == NO_PIECE )
        return MOVE_INVALID;

    if( x == dx && y == dy )
        return MOVE_INVALID;

    if( IS_WHITE( board->board[x][y] ) && !str_cmp( board->player1, ch->name ) )
        return MOVE_WRONGCOLOR;
    if( IS_BLACK( board->board[x][y] ) && ( !ch || !str_cmp( board->player2, ch->name ) ) )
        return MOVE_WRONGCOLOR;

    switch ( board->board[x][y] )
    {
    case WHITE_PAWN:
    case BLACK_PAWN:
        if( IS_WHITE( board->board[x][y] ) && dx == x + 2 && x == 1 && dy == y && board->board[dx][dy] == NO_PIECE && board->board[x + 1][dy] == NO_PIECE )
            return MOVE_OK;
        else if( IS_BLACK( board->board[x][y] ) && dx == x - 2 && x == 6 && dy == y && board->board[dx][dy] == NO_PIECE && board->board[x - 1][dy] == NO_PIECE )
            return MOVE_OK;
        if( IS_WHITE( board->board[x][y] ) && dx != x + 1 )
            return MOVE_INVALID;
        else if( IS_BLACK( board->board[x][y] ) && dx != x - 1 )
            return MOVE_INVALID;
        if( dy != y && dy != y - 1 && dy != y + 1 )
            return MOVE_INVALID;
        if( dy == y )
        {
            if( board->board[dx][dy] == NO_PIECE )
                return MOVE_OK;
            else if( SAME_COLOR( x, y, dx, dy ) )
                return MOVE_SAMECOLOR;
            else
                return MOVE_BLOCKED;
        }
        else
        {
            if( board->board[dx][dy] == NO_PIECE )
                return MOVE_INVALID;
            else if( SAME_COLOR( x, y, dx, dy ) )
                return MOVE_SAMECOLOR;
            else if( board->board[dx][dy] != BLACK_KING && board->board[dx][dy] != WHITE_KING )
                return MOVE_TAKEN;
            else
                return MOVE_INVALID;
        }
        break;
    case WHITE_ROOK:
    case BLACK_ROOK:
    {
        int cnt;

        if( dx != x && dy != y )
            return MOVE_INVALID;

        if( dx == x )
        {
            for( cnt = y; cnt != dy; )
            {
                if( cnt != y && board->board[x][cnt] != NO_PIECE )
                    return MOVE_BLOCKED;
                if( dy > y )
                    ++cnt;
                else
                    --cnt;
            }
        }
        else if( dy == y )
        {
            for( cnt = x; cnt != dx; )
            {
                if( cnt != x && board->board[cnt][y] != NO_PIECE )
                    return MOVE_BLOCKED;
                if( dx > x )
                    ++cnt;
                else
                    --cnt;
            }
        }

        if( board->board[dx][dy] == NO_PIECE )
            return MOVE_OK;

        if( !SAME_COLOR( x, y, dx, dy ) )
            return MOVE_TAKEN;

        return MOVE_SAMECOLOR;
    }
    break;
    case WHITE_KNIGHT:
    case BLACK_KNIGHT:
        if( ( dx == x - 2 && dy == y - 1 ) ||
                ( dx == x - 2 && dy == y + 1 ) ||
                ( dx == x - 1 && dy == y - 2 ) ||
                ( dx == x - 1 && dy == y + 2 ) ||
                ( dx == x + 1 && dy == y - 2 ) || ( dx == x + 1 && dy == y + 2 ) || ( dx == x + 2 && dy == y - 1 ) || ( dx == x + 2 && dy == y + 1 ) )
        {
            if( board->board[dx][dy] == NO_PIECE )
                return MOVE_OK;
            if( SAME_COLOR( x, y, dx, dy ) )
                return MOVE_SAMECOLOR;
            return MOVE_TAKEN;
        }
        return MOVE_INVALID;
        break;
    case WHITE_BISHOP:
    case BLACK_BISHOP:
    {
        int l, m, blocked = false;

        if( dx == x || dy == y )
            return MOVE_INVALID;

        l = x;
        m = y;

        while( 1 )
        {
            if( dx > x )
                ++l;
            else
                --l;
            if( dy > y )
                ++m;
            else
                --m;
            if( l > 7 || m > 7 || l < 0 || m < 0 )
                return MOVE_INVALID;
            if( l == dx && m == dy )
                break;
            if( board->board[l][m] != NO_PIECE )
                blocked = true;
        }
        if( l != dx || m != dy )
            return MOVE_INVALID;

        if( blocked )
            return MOVE_BLOCKED;

        if( board->board[dx][dy] == NO_PIECE )
            return MOVE_OK;

        if( !SAME_COLOR( x, y, dx, dy ) )
            return MOVE_TAKEN;

        return MOVE_SAMECOLOR;
    }
    break;
    case WHITE_QUEEN:
    case BLACK_QUEEN:
    {
        int l, m, blocked = false;

        l = x;
        m = y;

        while( 1 )
        {
            if( dx > x )
                ++l;
            else if( dx < x )
                --l;
            if( dy > y )
                ++m;
            else if( dy < y )
                --m;
            if( l > 7 || m > 7 || l < 0 || m < 0 )
                return MOVE_INVALID;
            if( l == dx && m == dy )
                break;
            if( board->board[l][m] != NO_PIECE )
                blocked = true;
        }
        if( l != dx || m != dy )
            return MOVE_INVALID;

        if( blocked )
            return MOVE_BLOCKED;

        if( board->board[dx][dy] == NO_PIECE )
            return MOVE_OK;

        if( !SAME_COLOR( x, y, dx, dy ) )
            return MOVE_TAKEN;

        return MOVE_SAMECOLOR;
    }
    break;
    case WHITE_KING:
    case BLACK_KING:
    {
        int sp, sk;
        if( dx > x + 1 || dx < x - 1 || dy > y + 1 || dy < y - 1 )
            return MOVE_INVALID;
        sk = board->board[x][y];
        sp = board->board[dx][dy];
        board->board[x][y] = sp;
        board->board[dx][dy] = sk;
        if( king_in_check( board, sk ) )
        {
            board->board[x][y] = sk;
            board->board[dx][dy] = sp;
            return MOVE_CHECK;
        }
        board->board[x][y] = sk;
        board->board[dx][dy] = sp;
        if( board->board[dx][dy] == NO_PIECE )
            return MOVE_OK;
        if( SAME_COLOR( x, y, dx, dy ) )
            return MOVE_SAMECOLOR;
        return MOVE_TAKEN;
    }
    break;
    default:
        bug( "Invaild piece: %d", board->board[x][y] );
        return MOVE_INVALID;
    }

    if( ( IS_WHITE( board->board[x][y] ) && IS_WHITE( board->board[dx][dy] ) ) || ( IS_BLACK( board->board[x][y] ) && IS_BLACK( board->board[dx][dy] ) ) )
        return MOVE_SAMECOLOR;

    return MOVE_OK;
}
예제 #4
0
파일: chess.cpp 프로젝트: xorith/AFKMud
bool king_in_check( game_board_data * board, int piece )
{
    int x = 0, y = 0, l, m;

    if( piece != WHITE_KING && piece != BLACK_KING )
        return false;

    if( !find_piece( board, &x, &y, piece ) )
        return false;

    if( x < 0 || y < 0 || x > 7 || y > 7 )
        return false;

    /*
     * pawns
     */
    if( IS_WHITE( piece ) && x < 7 && ( ( y > 0 && IS_BLACK( board->board[x + 1][y - 1] ) ) || ( y < 7 && IS_BLACK( board->board[x + 1][y + 1] ) ) ) )
        return true;
    else if( IS_BLACK( piece ) && x > 0 && ( ( y > 0 && IS_WHITE( board->board[x - 1][y - 1] ) ) || ( y < 7 && IS_WHITE( board->board[x - 1][y + 1] ) ) ) )
        return true;
    /*
     * knights
     */
    if( x - 2 >= 0 && y - 1 >= 0 &&
            ( ( board->board[x - 2][y - 1] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) ||
              ( board->board[x - 2][y - 1] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) )
        return true;
    if( x - 2 >= 0 && y + 1 < 8 &&
            ( ( board->board[x - 2][y + 1] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) ||
              ( board->board[x - 2][y + 1] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) )
        return true;

    if( x - 1 >= 0 && y - 2 >= 0 &&
            ( ( board->board[x - 1][y - 2] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) ||
              ( board->board[x - 1][y - 2] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) )
        return true;
    if( x - 1 >= 0 && y + 2 < 8 &&
            ( ( board->board[x - 1][y + 2] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) ||
              ( board->board[x - 1][y + 2] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) )
        return true;

    if( x + 1 < 8 && y - 2 >= 0 &&
            ( ( board->board[x + 1][y - 2] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) ||
              ( board->board[x + 1][y - 2] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) )
        return true;
    if( x + 1 < 8 && y + 2 < 8 &&
            ( ( board->board[x + 1][y + 2] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) ||
              ( board->board[x + 1][y + 2] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) )
        return true;

    if( x + 2 < 8 && y - 1 >= 0 &&
            ( ( board->board[x + 2][y - 1] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) ||
              ( board->board[x + 2][y - 1] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) )
        return true;
    if( x + 2 < 8 && y + 1 < 8 &&
            ( ( board->board[x + 2][y + 1] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) ||
              ( board->board[x + 2][y + 1] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) )
        return true;

    /*
     * horizontal/vertical long distance
     */
    for( l = x + 1; l < 8; ++l )
        if( board->board[l][y] != NO_PIECE )
        {
            if( SAME_COLOR( x, y, l, y ) )
                break;
            if( board->board[l][y] == BLACK_QUEEN || board->board[l][y] == WHITE_QUEEN || board->board[l][y] == BLACK_ROOK || board->board[l][y] == WHITE_ROOK )
                return true;
            break;
        }
    for( l = x - 1; l >= 0; --l )
        if( board->board[l][y] != NO_PIECE )
        {
            if( SAME_COLOR( x, y, l, y ) )
                break;
            if( board->board[l][y] == BLACK_QUEEN || board->board[l][y] == WHITE_QUEEN || board->board[l][y] == BLACK_ROOK || board->board[l][y] == WHITE_ROOK )
                return true;
            break;
        }
    for( m = y + 1; m < 8; ++m )
        if( board->board[x][m] != NO_PIECE )
        {
            if( SAME_COLOR( x, y, x, m ) )
                break;
            if( board->board[x][m] == BLACK_QUEEN || board->board[x][m] == WHITE_QUEEN || board->board[x][m] == BLACK_ROOK || board->board[x][m] == WHITE_ROOK )
                return true;
            break;
        }
    for( m = y - 1; m >= 0; --m )
        if( board->board[x][m] != NO_PIECE )
        {
            if( SAME_COLOR( x, y, x, m ) )
                break;
            if( board->board[x][m] == BLACK_QUEEN || board->board[x][m] == WHITE_QUEEN || board->board[x][m] == BLACK_ROOK || board->board[x][m] == WHITE_ROOK )
                return true;
            break;
        }
    /*
     * diagonal long distance
     */
    for( l = x + 1, m = y + 1; l < 8 && m < 8; ++l, ++m )
        if( board->board[l][m] != NO_PIECE )
        {
            if( SAME_COLOR( x, y, l, m ) )
                break;
            if( board->board[l][m] == BLACK_QUEEN || board->board[l][m] == WHITE_QUEEN || board->board[l][m] == BLACK_BISHOP || board->board[l][m] == WHITE_BISHOP )
                return true;
            break;
        }
    for( l = x - 1, m = y + 1; l >= 0 && m < 8; --l, ++m )
        if( board->board[l][m] != NO_PIECE )
        {
            if( SAME_COLOR( x, y, l, m ) )
                break;
            if( board->board[l][m] == BLACK_QUEEN || board->board[l][m] == WHITE_QUEEN || board->board[l][m] == BLACK_BISHOP || board->board[l][m] == WHITE_BISHOP )
                return true;
            break;
        }
    for( l = x + 1, m = y - 1; l < 8 && m >= 0; ++l, --m )
        if( board->board[l][m] != NO_PIECE )
        {
            if( SAME_COLOR( x, y, l, m ) )
                break;
            if( board->board[l][m] == BLACK_QUEEN || board->board[l][m] == WHITE_QUEEN || board->board[l][m] == BLACK_BISHOP || board->board[l][m] == WHITE_BISHOP )
                return true;
            break;
        }
    for( l = x - 1, m = y - 1; l >= 0 && m >= 0; --l, --m )
        if( board->board[l][m] != NO_PIECE )
        {
            if( SAME_COLOR( x, y, l, m ) )
                break;
            if( board->board[l][m] == BLACK_QUEEN || board->board[l][m] == WHITE_QUEEN || board->board[l][m] == BLACK_BISHOP || board->board[l][m] == WHITE_BISHOP )
                return true;
            break;
        }
    return false;
}
예제 #5
0
/*
 * Controlla e ritorna il tipo di mossa effettuata
 */
int is_valid_move( CHAR_DATA *ch, CHESSBOARD_DATA *board, int x, int y, int dx, int dy )
{
	if ( !ch )
	{
		send_log( NULL, LOG_BUG, "is_valid_move: ch è NULL" );
		return MOVE_INVALID;
	}

	if ( !board )
	{
		send_log( NULL, LOG_BUG, "is_valid_move: board è NULL" );
		return MOVE_INVALID;
	}

	if ( x < 0 || y < 0 || x >= 8 || y >= 8 )
	{
		send_log( NULL, LOG_BUG, "is_valid_move: coordinate passate errate: x=%d y =%d", x, y );
		return MOVE_INVALID;
	}

	if ( dx < 0 || dy < 0 || dx >= 8 || dy >= 8 )
	{
		send_log( NULL, LOG_BUG, "is_valid_move: coordinate passate errate: dx=%d dy =%d", dx, dy );
		return MOVE_OFFBOARD;
	}

	if ( board->piece[x][y] == PIECE_NONE )
	{
		send_to_char( ch, "Non trovo nessun pezzo in quella casella.\r\n" );
		return MOVE_INVALID;
	}

	if ( x == dx && y == dy )
	{
		send_to_char( ch, "La sorgente e l'arrivo della mossa sono identiche.\r\n" );
		return MOVE_INVALID;
	}

	if ( (board->color[x][y] == COLOR_WHITE && ch == board->player1)
	  || (board->color[x][y] == COLOR_BLACK && ch == board->player2) )
	{
		send_to_char( ch, "Sto cercando di muovere un pezzo che non è del mio colore.\r\n" );
		return MOVE_WRONGCOLOR;
	}

	switch ( board->piece[x][y] )
	{
	  default:
		send_log( NULL, LOG_BUG, "is_valid_move():chess.c invaild piece: %d", board->piece[x][y] );
		send_to_char( ch, "-> Mossa sbagliata, avverti i Coder <-" );
		return MOVE_INVALID;
		break;

	  case PIECE_PAWN:
		if ( board->color[x][y] == COLOR_WHITE && dx == x+2 && x == 1 && dy == y
		  && board->piece[dx][dy] == PIECE_NONE && board->piece[x+1][dy] == PIECE_NONE )
			return MOVE_OK;
		if ( board->color[x][y] == COLOR_BLACK && dx == x-2 && x == 6 && dy == y
		  && board->piece[dx][dy] == PIECE_NONE && board->piece[x-1][dy] == PIECE_NONE )
			return MOVE_OK;

		if ( (board->color[x][y] == COLOR_WHITE && dx != x+1)
		  || (board->color[x][y] == COLOR_BLACK && dx != x-1) )
		{
			send_to_char( ch, "Debbo muovere il pedone di un passo per volta, solo dalle caselle di partenza del pedone è consentito una mossa da 2.\r\n" );
			return MOVE_INVALID;
		}

		if ( dy != y && dy != y-1 && dy != y+1 )
		{
			send_to_char( ch, "Debbo muovere il pedone sempre in avanti, oppure in diagonale di una casella quando può fare gambetto.\r\n" );
			return MOVE_INVALID;
		}

		if ( dy == y )
		{
			if ( board->piece[dx][dy] == PIECE_NONE )
				return MOVE_OK;
			if ( SAME_COLOR(x, y, dx, dy) )
			{
				send_to_char( ch, "Non posso muovere dove c'è un'altro pezzo del mio stesso colore.\r\n" );
				return MOVE_SAMECOLOR;
			}

			send_to_char( ch, "Non posso eseguire questa mossa.\r\n" );
			return MOVE_BLOCKED;
		}
		else
		{
			if ( board->piece[dx][dy] == PIECE_NONE )
			{
				/* (FF) (bb) Bisognerebbe gestire anche il gambetto */
				send_to_char( ch, "Non c'è nessun pezzo da mangiare in quella casella.\r\n" );
				return MOVE_INVALID;
			}
			if ( SAME_COLOR(x, y, dx, dy) )
			{
				send_to_char( ch, "Non posso mangiare un pezzo del mio stesso colore.\r\n" );
				return MOVE_SAMECOLOR;
			}
			if ( board->piece[dx][dy] != PIECE_KING )
				return MOVE_TAKEN;

			send_to_char( ch, "Non posso fare questa mossa.\r\n" );
			return MOVE_INVALID;
		}
		break;

	  case PIECE_ROOK:
	  {
		int cnt;

		if ( dx != x && dy != y )
		{
			send_to_char( ch, "Devo muovere la torre verticalmente o orizzontalmente dalla propria posizione.\r\n" );
			return MOVE_INVALID;
		}

		if ( dx == x )
		{
			for ( cnt = y;  cnt != dy; )
			{
				if ( cnt != y && board->piece[x][cnt] != PIECE_NONE )
				{
					send_to_char( ch, "Non posso spostare la torre fino a lì, qualche pezzo blocca la strada" );
					return MOVE_BLOCKED;
				}
				if ( dy > y )
					cnt++;
				else
					cnt--;
			}
		}
		else if ( dy == y )
		{
			for ( cnt = x;  cnt != dx; )
			{
				if ( cnt != x && board->piece[cnt][y] != PIECE_NONE )
				{
					send_to_char( ch, "Non posso spostare la torre fino a lì, qualche pezzo blocca la strada" );
					return MOVE_BLOCKED;
				}
				if ( dx > x )
					cnt++;
				else
					cnt--;
			}
		}

		if ( board->piece[dx][dy] == PIECE_NONE )
			return MOVE_OK;

		if ( SAME_COLOR(x, y, dx, dy) )
		{
			send_to_char( ch, "Non posso mangiare un pezzo del mio stesso colore.\r\n" );
			return MOVE_SAMECOLOR;
		}

		return MOVE_TAKEN;
	  }
	  break;

	  case PIECE_KNIGHT:
		if ( (dx == x - 2 && dy == y - 1)
		  || (dx == x - 2 && dy == y + 1)
		  || (dx == x - 1 && dy == y - 2)
		  || (dx == x - 1 && dy == y + 2)
		  || (dx == x + 1 && dy == y - 2)
		  || (dx == x + 1 && dy == y + 2)
		  || (dx == x + 2 && dy == y - 1)
		  || (dx == x + 2 && dy == y + 1) )
		{
			if ( board->piece[dx][dy] == PIECE_NONE )
				return MOVE_OK;
			if ( SAME_COLOR(x, y, dx, dy) )
			{
				send_to_char( ch, "Non posso mangiare un pezzo del mio stesso colore.\r\n" );
				return MOVE_SAMECOLOR;
			}

			return MOVE_TAKEN;
		}
		send_to_char( ch, "Devo posso muovere il mio cavallo così.\r\n" );
		return MOVE_INVALID;
		break;

	  case PIECE_BISHOP:
	  {
		int	l;
		int	m;
		int	blocked = FALSE;

		if ( dx == x || dy == y )
		{
			send_to_char( ch, "Devo muovere l'alfiere diagonalmente dalla sua posizione.\r\n" );
			return MOVE_INVALID;
		}

		l = x;
		m = y;

		while ( 1 )
		{
			if ( dx > x )
				l++;
			else
				l--;

			if ( dy > y )
				m++;
			else
				m--;

			if ( l > 7 || m > 7 || l < 0 || m < 0 )
			{
				send_to_char( ch, "Non posso uscire dalla scacchiera.\r\n" );
				return MOVE_INVALID;
			}
			if ( l == dx && m == dy )
				break;

			if ( board->piece[l][m] != PIECE_NONE )
				blocked = TRUE;
		}

		if ( l != dx || m != dy )
		{
			send_to_char( ch, "Devo muovere l'alfiere diagonalmente dalla sua posizione.\r\n" );
			return MOVE_INVALID;
		}

		if ( blocked )
		{
			send_to_char( ch, "Non posso spostare il mio alfiere lì, qualche pezzo blocca la strada" );
			return MOVE_BLOCKED;
		}

		if ( board->piece[dx][dy] == PIECE_NONE )
			return MOVE_OK;

		if ( SAME_COLOR(x, y, dx, dy) )
		{
			send_to_char( ch, "Non posso mangaire un pezzo del mio stesso colore.\r\n" );
			return MOVE_SAMECOLOR;
		}

		return MOVE_TAKEN;
	  }
	  break;

	  case PIECE_QUEEN:
	  {
		int l;
		int m;
		int blocked = FALSE;

		l = x;
		m = y;

		while ( 1 )
		{
			if ( dx > x )
				l++;
			else if ( dx < x )
				l--;

			if ( dy > y )
				m++;
			else if ( dy < y )
				m--;

			if ( l > 7 || m > 7 || l < 0 || m < 0 )
			{
				send_to_char( ch, "Non posso muovere fuori dalla scacchiera.\r\n" );
				return MOVE_INVALID;
			}
			if ( l == dx && m == dy )
				break;

			if ( board->piece[l][m] != PIECE_NONE )
				blocked = TRUE;
		}

		if ( l != dx || m != dy )
		{
			send_to_char( ch, "Devo muovere la regina orizzonalmente, verticalmente o in diagonale dalla sua posizione.\r\n" );
			return MOVE_INVALID;
		}

		if ( blocked )
		{
			send_to_char( ch, "Non posso spostare la mia regina lì, qualche pezzo blocca la strada" );
			return MOVE_BLOCKED;
		}

		if ( board->piece[dx][dy] == PIECE_NONE )
			return MOVE_OK;

		if ( SAME_COLOR (x, y, dx, dy) )
		{
			send_to_char( ch, "Non posso mangiare un pezzo del mio stesso colore.\r\n" );
			return MOVE_SAMECOLOR;
		}

		return MOVE_TAKEN;
	  }
	  break;

	  case PIECE_KING:
	  {
		int		sp;
		int		spc;
		int		sk;
		int		skc;
		bool	incheck = FALSE;;

		if ( dx > x+1 || dx < x-1 || dy > y+1 || dy < y-1 )
		{
			send_to_char( ch, "Posso muovere il re di un solo passo attorno a sè, non oltre.\r\n" );
			return MOVE_INVALID;
		}

		if ( SAME_COLOR(x, y, dx, dy) )
		{
			send_to_char( ch, "Non posso mangiare un pezzo del mio stesso colore.\r\n" );
			return MOVE_SAMECOLOR;
		}

		sk	= board->piece[x][y];
		skc = board->color[x][y];
		sp	= board->piece[dx][dy];
		spc	= board->color[dx][dy];
		board->piece[x][y] = PIECE_NONE;
		board->piece[x][y] = COLOR_NONE;
		board->piece[dx][dy] = sk;
		board->color[dx][dy] = skc;

		if ( king_in_check(board, sk, skc) > 0 )
			incheck = TRUE;

		board->piece[x][y]	 = sk;
		board->color[x][y]	 = skc;
		board->piece[dx][dy] = sp;
		board->color[dx][dy] = spc;

		if ( incheck )
		{
			send_to_char( ch, "Non posso muovere il re in quella casella, sarebbe sotto scacco.\r\n" );
			return MOVE_CHECK;
		}

		if ( board->piece[dx][dy] == PIECE_NONE )
			return MOVE_OK;

		return MOVE_TAKEN;
	  }
	  break;
	}

	send_log( NULL, LOG_BUG, "is_valid_move: shouldn't get here" );
	send_to_char( ch, "-> Mossa sbagliata, avverti i Coder <-" );
	return MOVE_INVALID;
}
예제 #6
0
/*
 * Controlla se il re è sotto scacco
 * Ritorna il numero di pezzi che tengono sotto scacco il re
 */
int king_in_check( CHESSBOARD_DATA *board, const int piece, const int color )
{
	int		x = 0;
	int		y = 0;
	int		direction;
	int		count = 0;	/* conta quante volte contemporaneamente il re è sotto scacco */

	if ( !board )
	{
		send_log( NULL, LOG_BUG, "king_in_check: board passata è NULL" );
		return 0;
	}

	if ( piece < 0 || piece >= PIECE_NONE )
	{
		send_log( NULL, LOG_BUG, "king_in_check: pezzo passato errato: %d", piece );
		return 0;
	}

	if ( color < 0 || color >= COLOR_NONE )
	{
		send_log( NULL, LOG_BUG, "king_in_check: color passato errato: %d", color );
		return 0;
	}

	if ( piece != PIECE_KING )
		return 0;

	/* Cercando il pezzo nella scacchiera se lo trova imposta x e y con le coordinate del pezzo */
	if ( !find_piece(board, &x, &y, piece) )
		return 0;

	if ( x < 0 || y < 0 || x >= 8 || y >= 8 )
	{
		send_log( NULL, LOG_BUG, "king_in_check: coordinate del pezzo %s errate: x=%d y=%d",
			table_pieces[piece].name, x, y );
		return 0;
	}

	/* Pedoni - (??) ma qui se un cavallo si trova in posizione di scacco-pedone dà scacco anche lui?? manca il check che il tipo controllato sia un pedone secondo me */
	if ( board->color[x][y] == COLOR_WHITE && x < 7 && ((y > 0 && board->color[x+1][y-1] == COLOR_BLACK)
	  || (y < 7 && board->color[x+1][y+1] == COLOR_BLACK)) )
		count++;
	else if ( board->color[x][y] == COLOR_BLACK && x > 0 && ((y > 0 && board->color[x-1][y-1] == COLOR_WHITE)
	  || (y < 7 && board->color[x-1][y+1] == COLOR_WHITE)) )
		count++;

	/* Cavallo - il cavallo può eseguire una mossa in 8 direzioni max */
	for ( direction = 0;  direction < 8;  direction++ )
	{
		int	dirx = 0;
		int	diry = 0;

		/* Imposta le direzioni per ogni tipo di mossa-direzione */
		switch ( direction )
		{
		  case 0:	dirx = x - 2;	diry = y - 1;	break;
		  case 1:	dirx = x - 2;	diry = y + 1;	break;
		  case 2:	dirx = x - 1;	diry = y - 2;	break;
		  case 3:	dirx = x - 1;	diry = y + 2;	break;
		  case 4:	dirx = x + 1;	diry = y - 2;	break;
		  case 5:	dirx = x + 1;	diry = y + 2;	break;
		  case 6:	dirx = x + 2;	diry = y - 1;	break;
		  case 7:	dirx = x + 2;	diry = y + 1;	break;
		}

		/* Se supera i limiti della scacchiera ignora la mossa */
		if ( dirx <  0 )	continue;
		if ( dirx >= 8 )	continue;
		if ( diry <  0 )	continue;
		if ( diry >= 8 )	continue;

		/* Se nella direzione analizzata non ci sono pezzi ignora */
		if ( board->piece[dirx][diry] == PIECE_NONE )
			continue;

		/* Se il re e il cavallo hanno lo stesso colore ignora */
		if ( SAME_COLOR(x, y, dirx, diry) )
			continue;

		/* Se nella direzione analizza si trova un cavallo allora il re è sotto scacco */
		if ( board->piece[x+dirx][y+diry] == PIECE_KNIGHT )
			count++;
	}

	/* Alfiere, Torre, Regina - Controlla in una botta sola le 8 direzioni per i tre pezzi */
	for ( direction = 0;  direction < 8;  direction++ )
	{
		int	len;		/* lunghezza della ricerca nella direzione */
		int	dirx = 0;
		int	diry = 0;

		/* E' come se partisse da nord e poi continua in senso orario,
		 *	quindi le direzioni in diagonale sono quelle dispari */
		switch ( direction )
		{
		  case 0:	dirx =  0;	diry =  1;	break;	/* nord */
		  case 1:	dirx =  1;	diry =  1;	break;	/* nordest */
		  case 2:	dirx =  1;	diry =  0;	break;	/* est */
		  case 3:	dirx = -1;	diry =  1;	break;	/* sudest */
		  case 4:	dirx = -1;	diry =  0;	break;	/* sud */
		  case 5:	dirx = -1;	diry = -1;	break;	/* sudovest */
		  case 6:	dirx =  0;	diry = -1;	break;	/* ovest */
		  case 7:	dirx =  1;	diry = -1;	break;	/* nordovest */
		}

		/* Aumenta poco a poco il raggio di controllo nella direzione */
		for ( len = 1;  len < 8;  len++ )
		{
			dirx = x + (dirx * len);
			diry = y + (diry * len);

			/* Se supera i limiti della scacchiera ignora la ricerca in quella direzione */
			if ( dirx <  0 )	break;
			if ( dirx >= 8 )	break;
			if ( diry <  0 )	break;
			if ( diry >= 8 )	break;

			/* Se il re e il pezzo nella casella controllata hanno lo stesso colore si ferma */
			if ( SAME_COLOR(x, y, dirx, diry) )
				break;

			/* La regina si muove in tutte le direzioni, quindi il re è sotto scacco */
			if ( board->piece[dirx][diry] == PIECE_QUEEN )
				count++;
			/* L'alfiere si muove nelle diagonali */
			if ( board->piece[dirx][diry] == PIECE_BISHOP && (direction%2 == 1) )
				count++;
			/* Mentre la torre nelle direzioni orizzonatali e verticali */
			if ( board->piece[dirx][diry] == PIECE_BISHOP && (direction%2 == 0) )
				count++;

			/* Se c'è qualche altro pezzo nel controllo della direzione si ferma */
			if ( board->piece[dirx][diry] != PIECE_NONE )
				break;
		}
	}

	return count;
}