예제 #1
0
파일: position.c 프로젝트: alexmdc/chesslib
static ChessPiece promoted_piece(ChessMovePromote promote, ChessColor color)
{
    switch (promote)
    {
        case CHESS_MOVE_PROMOTE_KNIGHT:
            return chess_piece_of_color(CHESS_PIECE_WHITE_KNIGHT, color);
        case CHESS_MOVE_PROMOTE_BISHOP:
            return chess_piece_of_color(CHESS_PIECE_WHITE_BISHOP, color);
        case CHESS_MOVE_PROMOTE_ROOK:
            return chess_piece_of_color(CHESS_PIECE_WHITE_ROOK, color);
        case CHESS_MOVE_PROMOTE_QUEEN:
            return chess_piece_of_color(CHESS_PIECE_WHITE_QUEEN, color);
        default:
            assert(0);
            return 0;
    }
}
예제 #2
0
파일: position.c 프로젝트: alexmdc/chesslib
static ChessPiece captured_piece(ChessUnmoveCaptured captured, ChessColor color)
{
    switch (captured)
    {
        case CHESS_UNMOVE_CAPTURED_NONE:
            return CHESS_PIECE_NONE;
        case CHESS_UNMOVE_CAPTURED_PAWN:
            return chess_piece_of_color(CHESS_PIECE_WHITE_PAWN, color);
        case CHESS_UNMOVE_CAPTURED_KNIGHT:
            return chess_piece_of_color(CHESS_PIECE_WHITE_KNIGHT, color);
        case CHESS_UNMOVE_CAPTURED_BISHOP:
            return chess_piece_of_color(CHESS_PIECE_WHITE_BISHOP, color);
        case CHESS_UNMOVE_CAPTURED_ROOK:
            return chess_piece_of_color(CHESS_PIECE_WHITE_ROOK, color);
        case CHESS_UNMOVE_CAPTURED_QUEEN:
            return chess_piece_of_color(CHESS_PIECE_WHITE_QUEEN, color);
        default:
            assert(0);
            return 0;
    }
}
예제 #3
0
파일: position.c 프로젝트: alexmdc/chesslib
void chess_position_undo_move(ChessPosition* position, ChessUnmove unmove)
{
    ChessSquare from = chess_unmove_from(unmove);
    ChessSquare to = chess_unmove_to(unmove);
    ChessUnmoveCaptured captured = chess_unmove_captured(unmove);
    ChessUnmoveEp ep = chess_unmove_ep(unmove);

    ChessPiece piece;
    ChessColor other = position->to_move;
    ChessColor color = chess_color_other(other);
    ChessFile file;

    if (from == 0 && to == 0)
    {
        /* Null move */
        piece = CHESS_PIECE_NONE;
    }
    else
    {
        if (chess_unmove_promotion(unmove))
            piece = chess_piece_of_color(CHESS_PIECE_WHITE_PAWN, color);
        else
            piece = position->piece[to];
        assert(color == chess_piece_color(piece));

        /* Unmove the piece */
        position->piece[from] = piece;
        position->piece[to] = captured_piece(captured, other);

        /* Handle castling */
        if (piece == CHESS_PIECE_WHITE_KING && from == CHESS_SQUARE_E1)
        {
            if (to == CHESS_SQUARE_G1)
            {
                position->piece[CHESS_SQUARE_F1] = CHESS_PIECE_NONE;
                position->piece[CHESS_SQUARE_H1] = CHESS_PIECE_WHITE_ROOK;
            }
            else if (to == CHESS_SQUARE_C1)
            {
                position->piece[CHESS_SQUARE_D1] = CHESS_PIECE_NONE;
                position->piece[CHESS_SQUARE_A1] = CHESS_PIECE_WHITE_ROOK;
            }
        }
        else if (piece == CHESS_PIECE_BLACK_KING && from == CHESS_SQUARE_E8)
        {
            if (to == CHESS_SQUARE_G8)
            {
                position->piece[CHESS_SQUARE_F8] = CHESS_PIECE_NONE;
                position->piece[CHESS_SQUARE_H8] = CHESS_PIECE_BLACK_ROOK;
            }
            else if (to == CHESS_SQUARE_C8)
            {
                position->piece[CHESS_SQUARE_D8] = CHESS_PIECE_NONE;
                position->piece[CHESS_SQUARE_A8] = CHESS_PIECE_BLACK_ROOK;
            }
        }
        position->castle = chess_unmove_castle(unmove);
    }

    /* Handle ep */
    if (ep == CHESS_UNMOVE_EP_NONE)
    {
        position->ep = CHESS_FILE_INVALID;
    }
    else if (ep == CHESS_UNMOVE_EP_CAPTURE)
    {
        assert(piece == CHESS_PIECE_WHITE_PAWN || piece == CHESS_PIECE_BLACK_PAWN);

        /* Restore the captured pawn */
        file = chess_square_file(to);
        if (color == CHESS_COLOR_WHITE)
            position->piece[chess_square_from_fr(file, CHESS_RANK_5)] = CHESS_PIECE_BLACK_PAWN;
        else
            position->piece[chess_square_from_fr(file, CHESS_RANK_4)] = CHESS_PIECE_WHITE_PAWN;
        position->ep = file;
    }
    else
    {
        position->ep = ep - CHESS_UNMOVE_EP_AVAILABLE;
    }

    /* Update king positions */
    if (piece == CHESS_PIECE_WHITE_KING)
        position->wking = from;
    else if (piece == CHESS_PIECE_BLACK_KING)
        position->bking = from;

    /* Update move counters */
    position->fifty = chess_unmove_fifty(unmove);

    position->to_move = color;
    if (position->to_move == CHESS_COLOR_BLACK)
        position->move_num--;
}
예제 #4
0
ChessBoolean chess_generate_is_square_attacked(const ChessPosition* position, ChessSquare sq, ChessColor color)
{
    ChessSquare from;
    ChessPiece piece;
    int dirs, dir, d, dist;

    /* Check for knight attacks */
    dirs = jump_dirs[sq];
    for (d = 0; d < 8; d++)
    {
        dir = dirs_array[d];
        if ((dir & dirs) == 0)
            continue;

        from = sq + jumps_array[d];
        piece = chess_position_piece(position, from);
        if (chess_position_piece(position, from) == chess_piece_of_color(CHESS_PIECE_WHITE_KNIGHT, color))
            return CHESS_TRUE;
    }

    for (d = 0; d < 8; d++)
    {
        dir = dirs_array[d];
        from = sq;
        dist = 1;

        do
        {
            dirs = slide_dirs[from];
            if ((dir & dirs) == 0)
                break;

            from += slides_array[d];
            piece = chess_position_piece(position, from);
            if (piece != CHESS_PIECE_NONE && chess_piece_color(piece) == color)
            {
                switch (piece)
                {
                    case CHESS_PIECE_WHITE_QUEEN:
                    case CHESS_PIECE_BLACK_QUEEN:
                        return CHESS_TRUE;
                    case CHESS_PIECE_WHITE_BISHOP:
                    case CHESS_PIECE_BLACK_BISHOP:
                        if (dir & bishop_dirs)
                            return CHESS_TRUE;
                        break;
                    case CHESS_PIECE_WHITE_ROOK:
                    case CHESS_PIECE_BLACK_ROOK:
                        if (dir & rook_dirs)
                            return CHESS_TRUE;
                        break;
                    case CHESS_PIECE_WHITE_KING:
                    case CHESS_PIECE_BLACK_KING:
                        if (dist == 1)
                            return CHESS_TRUE;
                        break;
                    case CHESS_PIECE_WHITE_PAWN:
                        if (dist == 1 && dir & (DIR_SE | DIR_SW))
                            return CHESS_TRUE;
                        break;
                    case CHESS_PIECE_BLACK_PAWN:
                        if (dist == 1 && dir & (DIR_NE | DIR_NW))
                            return CHESS_TRUE;
                        break;
                    case CHESS_PIECE_WHITE_KNIGHT:
                    case CHESS_PIECE_BLACK_KNIGHT:
                        break;
                    default:
                        assert(CHESS_FALSE);
                        break;
                }
            }
            dist++;
        } while (piece == CHESS_PIECE_NONE);
    }

    return CHESS_FALSE;
}