Exemple #1
0
inline void bishop_move(struct position *pos, struct move_array *m,
            unsigned char bishops)
{
    uint64_t bishop_pos = pos->pieces[bishops];
    uint64_t moves;
    unsigned char index_from, index_to;
    for (int i = 0; i < 10; i++) {  // up to 10 bishops of same color on the board, (for loop for compiler loop unrolling)
        if ((index_from = ffsll(bishop_pos)) != 0) {
            index_from--;
            moves = BishopMoves[index_from][magictransform((pos->allpieces & BishopMasks[index_from]), BishopMagic[index_from], BishopMagicSize [index_from])] & ~pos-> sumpieces[bishops & COLOR];
            for (int i = 0; i < 14; i++) {
                if ((index_to = ffsll(moves)) != 0) {
                    index_to--;
                    add_move(m, index_from, index_to, bishops, find_piece(pos, index_to));
                    moves &= notlinboard[index_to];
                } else {
                    break;
                }
            }
            bishop_pos &= notlinboard[index_from];
        } else {
            break;
        }
    }
}
Exemple #2
0
int count_query(int a, int b){
  view_query(a,b);

  int L=0, cnt=0;
  ci_iter it1, it2;
  if (ci.count(a)){
    it1 = ci.lower_bound(a);
    L = it1->second.pos;
  } else {
    int L1,R1;
    it1 = find_piece(ci, N, a, L1, R1);
    for (int i=L1; i<R1; i++)
      if (arr[i] >= a && arr[i] < b) cnt++;
    L = R1;
    it1++;
  }
  assert(it1 != ci.end());
  it1++;

  if (ci.count(b)){
    it2 = ci.lower_bound(b);
  } else {
    int L2, R2;
    it2 = find_piece(ci, N, b, L2, R2);
    for (int i=L2; i<R2; i++)
      if (arr[i] >= a && arr[i] < b) cnt++;
    assert(it1 != it2);
    it2--;
  }

  while (true){
    cnt += it1->second.prev_pos() - L;
    L = it1->second.pos;
    if (it1 == it2) break;
    it1++;
  }
  return cnt;
}
Exemple #3
0
inline void king_move(struct position *pos, struct move_array *m, unsigned char king)
{
    unsigned char from = ffsll(pos->pieces[king]) - 1;
    uint64_t moves = kingmoves[from] & ~pos->sumpieces[king & COLOR];

    unsigned char index;
    for (int i = 0; i < 8; i++) {
        if ((index = ffsll(moves)) != 0) {
            index--;
            add_move(m, from, index, king, find_piece(pos, index));
            moves &= notlinboard[index];
        } else {
            break;
        }
    }
}
Exemple #4
0
/* This function exists for disambiguation purposes.
 * Piece 'piece' from coords (previous_x, previous_y) didn't move. Instead we'll
 * move the same type of piece from coords (new_x, new_y). The question is:
 * Does after this move our king will be save? */
bool is_king_defended_after_move(char piece, char new_x, signed char new_y, char previous_x, signed char previous_y, const char (*Board)[8])
{
	char king = (piece >= 'A' && piece <= 'Z' ? 'K' : 'k');  // white king can't be under attack after white's move
	char (*new_board)[8] = (char (*)[8])malloc(8 * 8 * sizeof(char));
	memcpy(new_board, Board, 8 * 8 * sizeof(char));
	new_board[8 - previous_y][previous_x - 'a'] = piece;
	new_board[8 - new_y][new_x - 'a'] = ' ';
	struct piece king_placement;
	if (find_piece(king, &king_placement, (const char (*)[8])new_board))
		if (is_piece_attacked(king, king_placement.alphabetical, king_placement.numerical, (const char (*)[8])new_board, 1) == 0) {
			free(new_board);
			return 1;
		}
	free(new_board);
	return 0;
}
Exemple #5
0
bool in_check(bool is_white)
{
	char tc, fc;
	int tr, fr;
	if (!find_piece(is_white ? 'K' : 'k', tc, tr)) return false;
	for (int i = 0; i < SZ; i++)
	{
		for (int j = 0; j < SZ; j++)
		{
			fc = int_to_char(j);
			fr = i + 1;
			if (iscol(fc, fr, !is_white))
			{
				switch (toupper(bd[i][j]))
				{
				case 'P':
					break;
				case 'N':
					if (KNCHK)
						return true;
					break;
				case 'B':
					if (BSCHK)
						return true;
					break;
				case 'R':
					if (RKCHK)
						return true;
					break;
				case 'Q':
					if (QNCHK)
						return true;
					break;
				case 'K':
					if (KGCHK)
						return true;
				default:
					break;
				}
			}
		}
	}
	return false;
}
Exemple #6
0
inline void knight_move(struct position *pos, struct move_array *m, unsigned char knights)
{
    uint64_t knight_pos = pos->pieces[knights];
    uint64_t moves;
    unsigned char index_from, index_to;
    for (int i = 0; i < 10; i++) {  // can have up to 10 knights of same color on the board, (for loop for compiler loop unrolling)
        if ((index_from = ffsll(knight_pos)) != 0) {
            index_from--;
            moves = knightmoves[index_from] & ~pos->sumpieces[knights & COLOR];
            for (int i = 0; i < 8; i++) {
                if ((index_to = ffsll(moves)) != 0) {
                    index_to--;
                    add_move(m, index_from, index_to, knights, find_piece(pos, index_to));
                    moves &= notlinboard[index_to];
                } else {
                    break;
                }
            }
            knight_pos &= notlinboard[index_from];
        } else {
            break;
        }
    }
}
Exemple #7
0
bool king_in_checkmate( game_board_data * board, int piece )
{
    int x = 0, y = 0, dx, dy, sk = 0;

    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;

    if( !king_in_check( board, board->board[x][y] ) )
        return false;

    dx = x + 1;
    dy = y + 1;
    if( dx < 8 && dy < 8 && board->board[dx][dy] == NO_PIECE )
    {
        sk = board->board[dx][dy] = board->board[x][y];
        board->board[x][y] = NO_PIECE;
        if( !king_in_check( board, sk ) )
        {
            board->board[x][y] = sk;
            board->board[dx][dy] = NO_PIECE;
            return false;
        }
        board->board[x][y] = sk;
        board->board[dx][dy] = NO_PIECE;
    }
    dx = x - 1;
    dy = y + 1;
    if( dx >= 0 && dy < 8 && board->board[dx][dy] == NO_PIECE )
    {
        sk = board->board[dx][dy] = board->board[x][y];
        board->board[x][y] = NO_PIECE;
        if( !king_in_check( board, sk ) )
        {
            board->board[x][y] = sk;
            board->board[dx][dy] = NO_PIECE;
            return false;
        }
        board->board[x][y] = sk;
        board->board[dx][dy] = NO_PIECE;
    }
    dx = x + 1;
    dy = y - 1;
    if( dx < 8 && dy >= 0 && board->board[dx][dy] == NO_PIECE )
    {
        sk = board->board[dx][dy] = board->board[x][y];
        board->board[x][y] = NO_PIECE;
        if( !king_in_check( board, sk ) )
        {
            board->board[x][y] = sk;
            board->board[dx][dy] = NO_PIECE;
            return false;
        }
        board->board[x][y] = sk;
        board->board[dx][dy] = NO_PIECE;
    }
    dx = x - 1;
    dy = y - 1;
    if( dx >= 0 && dy >= 0 && board->board[dx][dy] == NO_PIECE )
    {
        sk = board->board[dx][dy] = board->board[x][y];
        board->board[x][y] = NO_PIECE;
        if( !king_in_check( board, sk ) )
        {
            board->board[x][y] = sk;
            board->board[dx][dy] = NO_PIECE;
            return false;
        }
        board->board[x][y] = sk;
        board->board[dx][dy] = NO_PIECE;
    }
    dx = x;
    dy = y + 1;
    if( dy < 8 && board->board[dx][dy] == NO_PIECE )
    {
        sk = board->board[dx][dy] = board->board[x][y];
        board->board[x][y] = NO_PIECE;
        if( !king_in_check( board, sk ) )
        {
            board->board[x][y] = sk;
            board->board[dx][dy] = NO_PIECE;
            return false;
        }
        board->board[x][y] = sk;
        board->board[dx][dy] = NO_PIECE;
    }
    dx = x;
    dy = y - 1;
    if( dy >= 0 && board->board[dx][dy] == NO_PIECE )
    {
        sk = board->board[dx][dy] = board->board[x][y];
        board->board[x][y] = NO_PIECE;
        if( !king_in_check( board, sk ) )
        {
            board->board[x][y] = sk;
            board->board[dx][dy] = NO_PIECE;
            return false;
        }
        board->board[x][y] = sk;
        board->board[dx][dy] = NO_PIECE;
    }
    dx = x + 1;
    dy = y;
    if( dx < 8 && board->board[dx][dy] == NO_PIECE )
    {
        sk = board->board[dx][dy] = board->board[x][y];
        board->board[x][y] = NO_PIECE;
        if( !king_in_check( board, sk ) )
        {
            board->board[x][y] = sk;
            board->board[dx][dy] = NO_PIECE;
            return false;
        }
        board->board[x][y] = sk;
        board->board[dx][dy] = NO_PIECE;
    }
    dx = x - 1;
    dy = y;
    if( dx >= 0 && board->board[dx][dy] == NO_PIECE )
    {
        sk = board->board[dx][dy] = board->board[x][y];
        board->board[x][y] = NO_PIECE;
        if( !king_in_check( board, sk ) )
        {
            board->board[x][y] = sk;
            board->board[dx][dy] = NO_PIECE;
            return false;
        }
        board->board[x][y] = sk;
        board->board[dx][dy] = NO_PIECE;
    }
    return true;
}
Exemple #8
0
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;
}
Exemple #9
0
inline void pawn_move(struct position *pos, struct move_array *m, unsigned char pawns)
{
    uint64_t pawn_pos = pos->pieces[pawns];
    uint64_t moves;
    unsigned char index_to;
    switch (pawns & COLOR) {
    case WHITE:
        // nonpromotion forward moves 
        moves = moveN(pawn_pos) & ~pos->allpieces & ~rank[7];
        for (int i = 0; i < 8; i++) {
            if ((index_to = ffsll(moves)) != 0) {
                index_to--;
                add_move(m, index_to + S, index_to, pawns, nopiece_n);
                moves &= notlinboard[index_to];
            } else {
                break;
            }
        }

        // forward 2 moves 
        pawn_pos = pos->pieces[pawns];
        moves = moveN(moveN(pawn_pos) & ~pos->allpieces) & ~pos->allpieces & rank[3];
        for (int i = 0; i < 8; i++) {
            if ((index_to = ffsll(moves)) != 0) {
                index_to--;
                add_move_forward2(m, index_to + S + S, index_to, pawns, nopiece_n);
                moves &= notlinboard[index_to];
            } else {
                break;
            }
        }

        // nonpromotion attack west moves
        pawn_pos = pos->pieces[pawns];
        moves = moveNW(pawn_pos) & (pos->bpieces | ep_squares[1][pos->ep]) & ~file[7] & ~rank[7];
        for (int i = 0; i < 8; i++) {
            if ((index_to = ffsll(moves)) != 0) {
                index_to--;
                add_move(m, index_to + SE, index_to, pawns, find_piece_ep(pos, index_to));
                moves &= notlinboard[index_to];
            } else {
                break;
            }
        }

        // nonpromotion attack east moves
        pawn_pos = pos->pieces[pawns];
        moves = moveNE(pawn_pos) & (pos->bpieces | ep_squares[1][pos->ep]) & ~file[0] & ~rank[7];
        for (int i = 0; i < 8; i++) {
            if ((index_to = ffsll(moves)) != 0) {
                index_to--;
                add_move(m, index_to + SW, index_to, pawns, find_piece_ep(pos, index_to));
                moves &= notlinboard[index_to];
            } else {
                break;
            }
        }

        pawn_pos = pos->pieces[pawns];
        if ((pawn_pos & rank[6]) == 0) {    // no promotion possibilities
            return;
        } else {
            // promotion forward moves
            moves = moveN(pawn_pos) & ~pos->allpieces & rank[7];
            for (int i = 0; i < 8; i++) {
                if ((index_to = ffsll(moves)) != 0) {
                    index_to--;
                    add_promotion_move(m, index_to + S, index_to, pawns, nopiece_n);
                    moves &= notlinboard[index_to];
                } else {
                    break;
                }
            }

            // promotion attack west moves
            pawn_pos = pos->pieces[pawns];
            moves = moveNW(pawn_pos) & pos->bpieces & ~file[7] & rank[7];
            for (int i = 0; i < 8; i++) {
                if ((index_to = ffsll(moves)) != 0) {
                    index_to--;
                    add_promotion_move(m, index_to + SE, index_to, pawns, find_piece(pos, index_to));
                    moves &= notlinboard[index_to];
                } else {
                    break;
                }
            }

            // promotion attack east moves
            pawn_pos = pos->pieces[pawns];
            moves = moveNE(pawn_pos) & pos->bpieces & ~file[0] & rank[7];
            for (int i = 0; i < 8; i++) {
                if ((index_to = ffsll(moves)) != 0) {
                    index_to--;
                    add_promotion_move(m, index_to + SW, index_to, pawns, find_piece(pos, index_to));
                    moves &= notlinboard[index_to];
                } else {
                    break;
                }
            }
        }
        break;
    default: // black
        // nonpromotion forward moves 
        moves = moveS(pawn_pos) & ~pos->allpieces & ~rank[0];
        for (int i = 0; i < 8; i++) {
            if ((index_to = ffsll(moves)) != 0) {
                index_to--;
                add_move(m, index_to + N, index_to, pawns, nopiece_n);
                moves &= notlinboard[index_to];
            } else {
                break;
            }
        }

        // forward 2 moves 
        pawn_pos = pos->pieces[pawns];
        moves = moveS(moveS(pawn_pos) & ~pos->allpieces) & ~pos->allpieces & rank[4];
        for (int i = 0; i < 8; i++) {
            if ((index_to = ffsll(moves)) != 0) {
                index_to--;
                add_move_forward2(m, index_to + N + N, index_to, pawns, nopiece_n);
                moves &= notlinboard[index_to];
            } else {
                break;
            }
        }

        // nonpromotion attack west moves
        pawn_pos = pos->pieces[pawns];
        moves = moveSW(pawn_pos) & (pos->wpieces | ep_squares[0][pos->ep]) & ~file[7] & ~rank[0];
        for (int i = 0; i < 8; i++) {
            if ((index_to = ffsll(moves)) != 0) {
                index_to--;
                add_move(m, index_to + NE, index_to, pawns, find_piece_ep(pos, index_to));
                moves &= notlinboard[index_to];
            } else {
                break;
            }
        }

        // nonpromotion attack east moves
        pawn_pos = pos->pieces[pawns];
        moves = moveSE(pawn_pos) & (pos->wpieces | ep_squares[0][pos->ep]) & ~file[0] & ~rank[0];
        for (int i = 0; i < 8; i++) {
            if ((index_to = ffsll(moves)) != 0) {
                index_to--;
                add_move(m, index_to + NW, index_to, pawns, find_piece_ep(pos, index_to));
                moves &= notlinboard[index_to];
            } else {
                break;
            }
        }

        pawn_pos = pos->pieces[pawns];
        if ((pawn_pos & rank[1]) == 0) {    // no promotion possibilities
            return;
        } else {
            // promotion forward moves
            moves = moveS(pawn_pos) & ~pos->allpieces & rank[0];
            for (int i = 0; i < 8; i++) {
                if ((index_to = ffsll(moves)) != 0) {
                    index_to--;
                    add_promotion_move(m, index_to + N, index_to, pawns, nopiece_n);
                    moves &= notlinboard[index_to];
                } else {
                    break;
                }
            }

            // promotion attack west moves
            pawn_pos = pos->pieces[pawns];
            moves = moveSW(pawn_pos) & pos->wpieces & ~file[7] & rank[0];
            for (int i = 0; i < 8; i++) {
                if ((index_to = ffsll(moves)) != 0) {
                    index_to--;
                    add_promotion_move(m, index_to + NE, index_to, pawns, find_piece(pos, index_to));
                    moves &= notlinboard[index_to];
                } else {
                    break;
                }
            }

            // promotion attack east moves
            pawn_pos = pos->pieces[pawns];
            moves = moveSE(pawn_pos) & pos->wpieces & ~file[0] & rank[0];
            for (int i = 0; i < 8; i++) {
                if ((index_to = ffsll(moves)) != 0) {
                    index_to--;
                    add_promotion_move(m, index_to + NW, index_to, pawns, find_piece(pos, index_to));
                    moves &= notlinboard[index_to];
                } else {
                    break;
                }
            }
        }
        break;
    }
}
Exemple #10
0
/*
 * Controlla se il re sia in possibile scacco matto
 * (TT) Purtroppo questa parte è parziale, visto che si potrebbe coprire lo scacco con
 *	uno spostamento di un'altro pezzo, bisogna vedere in gioco come si comporta
 */
static bool king_in_possible_checkmate( CHESSBOARD_DATA *board, const int piece, const int color )
{
	int	x = 0;
	int	y = 0;
	int direction;

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

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

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

	if ( piece != PIECE_KING )
		return FALSE;

	/* Cercando il re nella scacchiera ritorna le coordinate del pezzo */
	if ( !find_piece(board, &x, &y, piece) )
		return FALSE;

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

	if ( king_in_check(board, board->piece[x][y], board->color[x][y]) == 0 )
		return FALSE;

	for ( direction = 0;  direction < 8;  direction++ )
	{
		int		dirx = 0;
		int		diry = 0;
		int		sk	= -1;
		int		skc = -1;
		bool	incheck = FALSE;

		switch ( direction )
		{
		  case 0:	dirx = x + 1;		diry = y + 1;
		  case 1:	dirx = x - 1;		diry = y + 1;
		  case 2:	dirx = x + 1;		diry = y - 1;
		  case 3:	dirx = x - 1;		diry = y - 1;
		  case 4:	dirx = x;			diry = y + 1;
		  case 5:	dirx = x;			diry = y - 1;
		  case 6:	dirx = x + 1;		diry = y;
		  case 7:	dirx = x - 1;		diry = y;
		}

		if ( dirx <  0 )	continue;
		if ( dirx >= 8 )	continue;
		if ( diry <  0 )	continue;
		if ( diry >= 8 )	continue;

		if ( board->piece[dirx][diry] == PIECE_NONE )
		{
			sk	= board->piece[dirx][diry] = board->piece[x][y];
			skc = board->color[dirx][diry] = board->color[x][y];
			board->piece[x][y] = PIECE_NONE;
			board->color[x][y] = COLOR_NONE;
			if ( king_in_check(board, sk, skc) == 0 )
				incheck = TRUE;

			board->piece[x][y] = sk;
			board->color[x][y] = skc;
			board->piece[dirx][diry] = PIECE_NONE;
			board->color[dirx][diry] = COLOR_NONE;

			if ( incheck )
				return FALSE;
		}
	}

	return TRUE;
}
Exemple #11
0
void naive_random_crack(){
  value_type x = arr[rr.nextInt(N)];
  int L,R; find_piece(ci, N, x,L,R);
  n_touched += R-L;
  add_crack(ci, N, x, partition(arr, x,L,R));
}
Exemple #12
0
/*
*	check if the color-king is checked (assuming there is a king on the board)
*/
int is_king_checked(int color, char board[BOARD_SIZE][BOARD_SIZE]) {
	char piece = (color == BLACK) ? BLACK_K : WHITE_K;
	cord c = find_piece(piece, board);
	return is_cord_checked(c, color, board);
}
Exemple #13
0
int main(int argc, char *argv[])
{
	const char *const Help = "fens2pgn - converts multiple FENs into single PGN file\n"
	"Syntax: fens2pgn [arguments] [output file] [input file]\n"
	"Arguments:\n"
	"  -f    force validity of every chess move\n"
	"  -o    take next argument as output file\n"
	"  -q    quiet - doesn't print informations to stderr\n"
	"  -v    verbose - notify of every skipped FEN\n"
	"  -h, --help    print this help text\n"
	"  -u, --usage   short usage information\n"
	"  -V, --version display program version";
	if (argc < 2) {
		puts(Help);
		return 0;
	}
	struct {
		bool validate;
		bool quiet;
		bool verbose;
		char *read_from_file;
		char *write_to_file;
	} parameters = {0, 0, 0, NULL, NULL};
	const struct option long_options[] = {
		{"help", 0, NULL, 'h'},
		{"usage", 0, NULL, 'u'},
		{"version", 0, NULL, 'V'},
		{NULL, 0, NULL, 0}
	};
	for (int option, long_option_index; (option = getopt_long(argc, argv, "fho:quvV", long_options, &long_option_index)) != -1;)
		switch (option) {
			case 'f':
				parameters.validate = 1;
				break;
			case 'h':
				puts(Help);
				return 0;
			case 'o':
				parameters.write_to_file = optarg;
				break;
			case 'q':
				parameters.quiet = 1;
				parameters.verbose = 0;
				break;
			case 'u':
				puts("Syntax: fens2pgn [-fqv] [-o OUTPUT_FILE] [INPUT_FILE]\n"
				"                 [-h|--help] [-u|--usage] [-V|--version]");
				return 0;
			case 'v':
				parameters.quiet = 0;
				parameters.verbose = 1;
				break;
			case 'V':
				puts("fens2pgn " VERSION "\n"
				"Copyright (C) 2015 Paweł Zacharek");
				return 0;
			default:
				return EINVAL;
		}
	if (optind == argc - 1)  // 1 unknown parameter (input file name)
		parameters.read_from_file = argv[optind];
	else if (optind != argc) {  // more unknown parameters
		fputs("Invalid argument(s) found.\n", stderr);
		return EINVAL;
	}
	FILE *input = (parameters.read_from_file == NULL ? stdin : fopen(parameters.read_from_file, "r"));
	FILE *output = (parameters.write_to_file == NULL ? stdout : fopen(parameters.write_to_file, "w"));
	if (input == NULL) {
		fprintf(stderr, "Can't open file \"%.255s\" for reading.\n", parameters.read_from_file);
		return ENOENT;
	}
	if (output == NULL) {
		fprintf(stderr, "Can't open file \"%.255s\" for writing.\n", parameters.read_from_file);
		return EACCES;
	}
	char fen_buffer[MAX_FEN_LENGHT + 1], fen_placement_buffer[MAX_PLACEMENT_LENGHT + 1];
	char store_space[STORE_SPACE_SIZE], store_move[STORE_MOVE_SIZE];
	char board_buffer_1[8][8], board_buffer_2[8][8];
	char (*board_1)[8] = board_buffer_1, (*board_2)[8] = board_buffer_2;
	int fen_number = 0, move_number = 1, number_of_characters_in_line = 0;
	struct field distinctions[4], *field, *previous_field;
	struct piece king_placement;
	signed char number_of_differences;
	char control_character, whose_move = 'w', castling_prospects[4 + 1] = "KQkq", en_passant_field[2 + 1] = "-";
	char control_string[8 + 1], result[7 + 1];  // to store respectively "Result \"" and "1/2-1/2"
	result[0] = '\0';
	bool metadata_included = 0, fens_are_incomplete = 0, first_move_number_already_written = 0, move_is_invalid = 0;
	// beginning of METADATA section
	fscanf(input, " %c", &control_character);
	while (control_character == '[') {
		metadata_included = 1;
		putc('[', output);
		if (fscanf(input, "%8[^\n]", control_string) == 1) {
			if (strncmp(control_string, "Result \"", 8) == 0 && fscanf(input, "%7[-01/2*]", result) == 1)
				fprintf(output, "%s%s", control_string, result);
			else
				fputs(control_string, output);
		}
		for (int character; (character = getc(input)) != EOF;) {
			putc(character, output);
			if (character == '\n')
				break;
		}
		fscanf(input, " %c", &control_character);
	}
	ungetc(control_character, input);
	// beginning of GAME section
	if (fscanf(input, "%" STR(MAX_FEN_LENGHT) "[-0-9a-h/rnqkpRNBQKP w]", fen_buffer) != 1) {  // reading the first FEN
		fputs("No valid FEN found.\n", stderr);
		return EILSEQ;
	}
	++fen_number;
	sscanf(fen_buffer, "%" STR(MAX_PLACEMENT_LENGHT) "[1-8/rnbqkpRNBQKP]", fen_placement_buffer);
	if (strncmp(fen_buffer, "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", 56) != 0) {  // it isn't classical complete FEN
		if (sscanf(fen_buffer, "%*[1-8/rnbqkpRNBQKP] %c %4s %2s %*d %d", &whose_move, castling_prospects, en_passant_field, &move_number) != 4) {  // FENs are incomplete
			fens_are_incomplete = 1;
			if (parameters.quiet != 1)
				fputs("FENs considered incomplete.\n", stderr);  // not corrupts redirected output
			whose_move = 'w';
			strcpy(castling_prospects, "KQkq");
			strcpy(en_passant_field, "-");
			move_number = 1;
		}
		if (fens_are_incomplete == 0 || strncmp(fen_buffer, "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR", 43) != 0)  // starting position isn't classical
			fprintf(output, "[SetUp \"1\"]\n[FEN \"%s\"]\n", fen_buffer);
	}
	if (metadata_included == 1)
		putc('\n', output);
	if (fen2board(fen_placement_buffer, board_1, parameters.validate) == 0) {
		fputs("There are more than 2 kings or invalid pieces on the first board. Terminating.\n", stderr);
		return 0;
	}
	for (;;) {
		if (fscanf(input, " %" STR(MAX_FEN_LENGHT) "[-0-9a-h/rnqkpRNBQKP w]", fen_buffer) != 1)
			break;
		++fen_number;
		sscanf(fen_buffer, "%" STR(MAX_PLACEMENT_LENGHT) "[1-8/rnbqkpRNBQKP]", fen_placement_buffer);
		if (fen2board(fen_placement_buffer, board_2, parameters.validate) == 0) {
			fprintf(stderr, "There are more than 2 kings or invalid pieces on board nr %d. Terminating.\n", fen_number);
			return 0;
		}
		number_of_differences = compare_boards((const char (*)[8])board_1, (const char (*)[8])board_2, distinctions);
		if (number_of_differences < 2) {
			if (parameters.verbose == 1)
				fprintf(stderr, "Skipped \"%s\" (%d%s FEN).\n", fen_buffer, fen_number, Ordinal_Number_Suffix(fen_number));
			continue;
		}
		if (number_of_differences > 4) {
			fprintf(stderr, "Can't compare \"%s\" (%d%s FEN) with the previous one.\n", fen_buffer, fen_number, Ordinal_Number_Suffix(fen_number));
			return EILSEQ;
		}
		switch (number_of_differences) {
			case 2:  // ordinary move or capture
				if (distinctions[0].piece_after != ' ') {
					field = &distinctions[0];
					previous_field = &distinctions[1];
				} else {  // it means that (distinctions[1].piece_after != ' ')
					field = &distinctions[1];
					previous_field = &distinctions[0];
				}
				switch (what_to_write((const char (*)[8])board_2, (const struct field *)field, (const struct field *)previous_field, en_passant_field, parameters.validate, whose_move, castling_prospects)) {
					case PAWN_MOVE:
						snprintf(store_move, STORE_MOVE_SIZE, "%c%hhd", field->alphabetical, field->numerical);
						break;
					case PAWN_CAPTURE:
						snprintf(store_move, STORE_MOVE_SIZE, "%cx%c%hhd", previous_field->alphabetical, field->alphabetical, field->numerical);
						break;
					case PAWN_PROMOTION:
						snprintf(store_move, STORE_MOVE_SIZE, "%c%hhd=%c", field->alphabetical, field->numerical, toupper(field->piece_after));
						break;
					case PAWN_CAPTURE_PROMOTION:
						snprintf(store_move, STORE_MOVE_SIZE, "%cx%c%hhd=%c", previous_field->alphabetical, field->alphabetical, field->numerical, toupper(field->piece_after));
						break;
					case PIECE_MOVE:
						snprintf(store_move, STORE_MOVE_SIZE, field->piece_before != ' ' ? "%cx%c%hhd" : "%c%c%hhd", toupper(field->piece_after), field->alphabetical, field->numerical);
						break;
					case DIS_LINE:
					case DIS_WHICHEVER:
						snprintf(store_move, STORE_MOVE_SIZE, field->piece_before != ' ' ? "%c%cx%c%hhd" : "%c%c%c%hhd", toupper(field->piece_after), previous_field->alphabetical, field->alphabetical, field->numerical);
						break;
					case DIS_COLUMN:
						snprintf(store_move, STORE_MOVE_SIZE, field->piece_before != ' ' ? "%c%hhdx%c%hhd" : "%c%hhd%c%hhd", toupper(field->piece_after), previous_field->numerical, field->alphabetical, field->numerical);
						break;
					case DIS_BOTH:
						snprintf(store_move, STORE_MOVE_SIZE, field->piece_before != ' ' ? "%c%c%hhdx%c%hhd" : "%c%c%hhd%c%hhd", toupper(field->piece_after), previous_field->alphabetical, previous_field->numerical, field->alphabetical, field->numerical);
						break;
					case INVALID_MOVE:
						move_is_invalid = 1;
						break;
					}
				break;
			case 3:  // en passant capture
				if (parameters.validate != 1) {
					if (whose_move == 'w')
						snprintf(store_move, STORE_MOVE_SIZE, "%cx%c%hhd", distinctions[0].alphabetical == distinctions[2].alphabetical ? distinctions[1].alphabetical : distinctions[2].alphabetical, distinctions[0].alphabetical, distinctions[0].numerical);
					else
						snprintf(store_move, STORE_MOVE_SIZE, "%cx%c%hhd", distinctions[0].alphabetical == distinctions[2].alphabetical ? distinctions[1].alphabetical : distinctions[0].alphabetical, distinctions[2].alphabetical, distinctions[2].numerical);
				} else {
					char all_fields[6 + 1];
					snprintf(all_fields, sizeof all_fields, "%c%c%c%c%c%c", distinctions[0].piece_before, distinctions[0].piece_after, distinctions[1].piece_before, distinctions[1].piece_after, distinctions[2].piece_before, distinctions[2].piece_after);
					if (whose_move == 'w' && en_passant_field[0] == distinctions[0].alphabetical && en_passant_field[1] - '0' == distinctions[0].numerical && distinctions[0].numerical == distinctions[2].numerical + 1 && distinctions[1].alphabetical == distinctions[2].alphabetical - 1 && (
						distinctions[0].alphabetical == distinctions[2].alphabetical && memcmp(all_fields, " PP p ", 6) == 0
						|| distinctions[0].alphabetical != distinctions[2].alphabetical && memcmp(all_fields, " Pp P ", 6) == 0
					))
						snprintf(store_move, STORE_MOVE_SIZE, "%cx%c%hhd", distinctions[0].alphabetical == distinctions[2].alphabetical ? distinctions[1].alphabetical : distinctions[2].alphabetical, distinctions[0].alphabetical, distinctions[0].numerical);
					else if (whose_move == 'b' && en_passant_field[0] == distinctions[2].alphabetical && en_passant_field[1] - '0' == distinctions[2].numerical && distinctions[0].numerical == distinctions[2].numerical + 1 && distinctions[0].alphabetical == distinctions[1].alphabetical - 1 && (
						distinctions[0].alphabetical == distinctions[2].alphabetical && memcmp(all_fields, "P p  p", 6) == 0
						|| distinctions[0].alphabetical != distinctions[2].alphabetical && memcmp(all_fields, "p P  p", 6) == 0
					))
						snprintf(store_move, STORE_MOVE_SIZE, "%cx%c%hhd", distinctions[0].alphabetical == distinctions[2].alphabetical ? distinctions[1].alphabetical : distinctions[0].alphabetical, distinctions[2].alphabetical, distinctions[2].numerical);
					else
						move_is_invalid = 1;
				}
				break;
			case 4:  // castling
				if (parameters.validate != 1)
					snprintf(store_move, STORE_MOVE_SIZE, distinctions[0].alphabetical == 'a' ? "O-O-O" : "O-O");
				else {
					if (distinctions[0].alphabetical == 'a' && is_king_checked_while_castling(distinctions[3].piece_before, distinctions[3].alphabetical, distinctions[3].numerical, (const char (*)[8])board_1, (const char (*)[8])board_2, -1) == 0 && (
						whose_move == 'w' && strchr(castling_prospects, 'Q') != NULL && memcmp(&board_1[8 - 1][0], "R   K", 5) == 0 && memcmp(&board_2[8 - 1][0], "  KR ", 5) == 0
						|| whose_move == 'b' && strchr(castling_prospects, 'q') != NULL && memcmp(&board_1[8 - 8][0], "r   k", 5) == 0 && memcmp(&board_2[8 - 8][0], "  kr ", 5) == 0
					))
						snprintf(store_move, STORE_MOVE_SIZE, "O-O-O");
					else if (distinctions[3].alphabetical == 'h' && is_king_checked_while_castling(distinctions[0].piece_before, distinctions[0].alphabetical, distinctions[0].numerical, (const char (*)[8])board_1, (const char (*)[8])board_2, 1) == 0 && (
						whose_move == 'w' && strchr(castling_prospects, 'K') != NULL && memcmp(&board_1[8 - 1][4], "K  R", 4) == 0 && memcmp(&board_2[8 - 1][0], " RK ", 4) == 0
						|| whose_move == 'b' && strchr(castling_prospects, 'k') != NULL && memcmp(&board_1[8 - 8][4], "k  r", 4) == 0 && memcmp(&board_2[8 - 8][0], " rk ", 4) == 0
					))
						snprintf(store_move, STORE_MOVE_SIZE, "O-O");
					else
						move_is_invalid = 1;
				}
				break;
		}
		if (parameters.validate == 1 && move_is_invalid == 1) {
			move_is_invalid = 0;
			if (parameters.quiet != 1)
				fprintf(stderr, "Skipped \"%s\" (%d%s FEN) because the calculated move is invalid.\n", fen_buffer, fen_number, Ordinal_Number_Suffix(fen_number));
			continue;
		}
		if (parameters.validate == 1 && find_piece(whose_move == 'w' ? 'K' : 'k', &king_placement, (const char (*)[8])board_2))
			if (is_piece_attacked(king_placement.type, king_placement.alphabetical, king_placement.numerical, (const char (*)[8])board_2, 1)) {
				if (parameters.quiet != 1)
					fprintf(stderr, "Skipped \"%s\" (%d%s FEN) because we're still in check.\n", fen_buffer, fen_number, Ordinal_Number_Suffix(fen_number));
				continue;
			}
		if (find_piece(whose_move == 'w' ? 'k' : 'K', &king_placement, (const char (*)[8])board_2))
			if (is_piece_attacked(king_placement.type, king_placement.alphabetical, king_placement.numerical, (const char (*)[8])board_2, 1)) {  // king is checked
				if (does_king_cannot_move((const struct piece *)&king_placement, board_2) && (
					is_piece_attacked(king_placement.type, king_placement.alphabetical, king_placement.numerical, (const char (*)[8])board_2, 2)  // double check
					|| is_it_checkmate(king_placement.alphabetical, king_placement.numerical, (const char (*)[8])board_2, (const char *)en_passant_field)
				))
					snprintf(store_move + strlen(store_move), STORE_MOVE_SIZE - strlen(store_move), "#");
				else
					snprintf(store_move + strlen(store_move), STORE_MOVE_SIZE - strlen(store_move), "+");
			}
		if (first_move_number_already_written == 1)
			strcpy(store_space, " ");
		if (whose_move == 'w' || first_move_number_already_written == 0)
			snprintf(store_space + (first_move_number_already_written ? 1 : 0), STORE_SPACE_SIZE - (first_move_number_already_written ? 1 : 0), "%d. ", move_number);
		number_of_characters_in_line += strlen(store_space) - 1;  // we can omit trailing space
		if (number_of_characters_in_line >= 80) {
			store_space[0] = '\n';
			number_of_characters_in_line = strlen(store_space) - 2;  // the first space is also not included
		}
		number_of_characters_in_line += strlen(store_move) + 1;  // add previously disregarded trailing space
		if (number_of_characters_in_line >= 80) {
			store_space[strlen(store_space) - 1] = '\n';
			number_of_characters_in_line = strlen(store_move);  // doesn't count trailing space of 'store_space' array
		}
		fprintf(output, "%s%s", store_space, store_move);
		first_move_number_already_written = 1;
		if (whose_move == 'b')
			++move_number;
		whose_move = (whose_move == 'b' ? 'w' : 'b');
		swap_pointers((void **)&board_1, (void **)&board_2);
	}
	if (result[0] != '\0')
		fprintf(output, "%c%s\n", number_of_characters_in_line + 1 + strlen(result) >= 80 ? '\n' : ' ', result);
	else
		fprintf(output, "%c*\n", number_of_characters_in_line + 2 >= 80 ? '\n' : ' ');
	fclose(input);
	fclose(output);
	return 0;
}
Exemple #14
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;
}
Exemple #15
0
int ddr_find(value_type v){
  int L,R;
  find_piece(ci, N, v, L,R);
  n_touched += R - L;
  return targeted_random_crack3(ci,v,arr,N,L,R,CRACK_AT);
}
Exemple #16
0
static bool king_in_checkmate( GAME_BOARD_DATA * board, int piece )
{
	int x = 0, y = 0, dx, dy, sk = 0;

	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;

	if ( !king_in_check( board, board->board[x][y] ) )
		return FALSE;

	dx = x + 1;
	dy = y + 1;
	if ( dx < 8 && dy < 8 && board->board[dx][dy] == NO_PIECE )
	{
		sk = board->board[dx][dy] = board->board[x][y];
		board->board[x][y] = NO_PIECE;
		if ( !king_in_check( board, sk ) )
		{
			board->board[x][y] = sk;
			board->board[dx][dy] = NO_PIECE;
			return FALSE;
		}
		board->board[x][y] = sk;
		board->board[dx][dy] = NO_PIECE;
	}
	dx = x - 1;
	dy = y + 1;
	if ( dx >= 0 && dy < 8 && board->board[dx][dy] == NO_PIECE )
	{
		sk = board->board[dx][dy] = board->board[x][y];
		board->board[x][y] = NO_PIECE;
		if ( !king_in_check( board, sk ) )
		{
			board->board[x][y] = sk;
			board->board[dx][dy] = NO_PIECE;
			return FALSE;
		}
		board->board[x][y] = sk;
		board->board[dx][dy] = NO_PIECE;
	}
	dx = x + 1;
	dy = y - 1;
	if ( dx < 8 && dy >= 0 && board->board[dx][dy] == NO_PIECE )
	{
		sk = board->board[dx][dy] = board->board[x][y];
		board->board[x][y] = NO_PIECE;
		if ( !king_in_check( board, sk ) )
		{
			board->board[x][y] = sk;
			board->board[dx][dy] = NO_PIECE;
			return FALSE;
		}
		board->board[x][y] = sk;
		board->board[dx][dy] = NO_PIECE;
	}
	dx = x - 1;
	dy = y - 1;
	if ( dx >= 0 && dy >= 0 && board->board[dx][dy] == NO_PIECE )
	{
		sk = board->board[dx][dy] = board->board[x][y];
		board->board[x][y] = NO_PIECE;
		if ( !king_in_check( board, sk ) )
		{
			board->board[x][y] = sk;
			board->board[dx][dy] = NO_PIECE;
			return FALSE;
		}
		board->board[x][y] = sk;
		board->board[dx][dy] = NO_PIECE;
	}
	dx = x;
	dy = y + 1;
	if ( dy < 8 && board->board[dx][dy] == NO_PIECE )
	{
		sk = board->board[dx][dy] = board->board[x][y];
		board->board[x][y] = NO_PIECE;
		if ( !king_in_check( board, sk ) )
		{
			board->board[x][y] = sk;
			board->board[dx][dy] = NO_PIECE;
			return FALSE;
		}
		board->board[x][y] = sk;
		board->board[dx][dy] = NO_PIECE;
	}
	dx = x;
	dy = y - 1;
	if ( dy >= 0 && board->board[dx][dy] == NO_PIECE )
	{
		sk = board->board[dx][dy] = board->board[x][y];
		board->board[x][y] = NO_PIECE;
		if ( !king_in_check( board, sk ) )
		{
			board->board[x][y] = sk;
			board->board[dx][dy] = NO_PIECE;
			return FALSE;
		}
		board->board[x][y] = sk;
		board->board[dx][dy] = NO_PIECE;
	}
	dx = x + 1;
	dy = y;
	if ( dx < 8 && board->board[dx][dy] == NO_PIECE )
	{
		sk = board->board[dx][dy] = board->board[x][y];
		board->board[x][y] = NO_PIECE;
		if ( !king_in_check( board, sk ) )
		{
			board->board[x][y] = sk;
			board->board[dx][dy] = NO_PIECE;
			return FALSE;
		}
		board->board[x][y] = sk;
		board->board[dx][dy] = NO_PIECE;
	}
	dx = x - 1;
	dy = y;
	if ( dx >= 0 && board->board[dx][dy] == NO_PIECE )
	{
		sk = board->board[dx][dy] = board->board[x][y];
		board->board[x][y] = NO_PIECE;
		if ( !king_in_check( board, sk ) )
		{
			board->board[x][y] = sk;
			board->board[dx][dy] = NO_PIECE;
			return FALSE;
		}
		board->board[x][y] = sk;
		board->board[dx][dy] = NO_PIECE;
	}
	return TRUE;
}
Exemple #17
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;
}