X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fuci.cpp;h=ae34043831cb19f39fa96fd7c9f677f7d68733a0;hp=6593d5ad25a6fe71f14b9b2c57f0c6071285f42e;hb=1e7aaed8bc;hpb=a46b53e1c21ba56b09d7d9e47335d383b5240ce0 diff --git a/src/uci.cpp b/src/uci.cpp index 6593d5ad..ae340438 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -23,6 +23,7 @@ //// #include +#include #include #include #include @@ -53,6 +54,7 @@ namespace { void set_position(Position& pos, UCIParser& up); bool go(Position& pos, UCIParser& up); void perft(Position& pos, UCIParser& up); + Move parse_uci_move(const Position& pos, const std::string &str); } @@ -132,6 +134,75 @@ bool execute_uci_command(const string& cmd) { namespace { + // parse_uci_move() takes a position and a string as input, and attempts to + // convert the string to a move, using simple coordinate notation (g1f3, + // a7a8q, etc.). In order to correctly parse en passant captures and castling + // moves, we need the position. This function is not robust, and expects that + // the input move is legal and correctly formatted. + + Move parse_uci_move(const Position& pos, const std::string& str) { + + Square from, to; + Piece piece; + Color us = pos.side_to_move(); + + if (str.length() < 4) + return MOVE_NONE; + + // Read the from and to squares + from = make_square(file_from_char(str[0]), rank_from_char(str[1])); + to = make_square(file_from_char(str[2]), rank_from_char(str[3])); + + // Find the moving piece + piece = pos.piece_on(from); + + // If the string has more than 4 characters, try to interpret the 5th + // character as a promotion. + if (str.length() > 4 && piece == piece_of_color_and_type(us, PAWN)) + { + switch (tolower(str[4])) { + case 'n': + return make_promotion_move(from, to, KNIGHT); + case 'b': + return make_promotion_move(from, to, BISHOP); + case 'r': + return make_promotion_move(from, to, ROOK); + case 'q': + return make_promotion_move(from, to, QUEEN); + } + } + + // En passant move? We assume that a pawn move is an en passant move + // if the destination square is epSquare. + if (to == pos.ep_square() && piece == piece_of_color_and_type(us, PAWN)) + return make_ep_move(from, to); + + // Is this a castling move? A king move is assumed to be a castling move + // if the destination square is occupied by a friendly rook, or if the + // distance between the source and destination squares is more than 1. + if (piece == piece_of_color_and_type(us, KING)) + { + if (pos.piece_on(to) == piece_of_color_and_type(us, ROOK)) + return make_castle_move(from, to); + + if (square_distance(from, to) > 1) + { + // This is a castling move, but we have to translate it to the + // internal "king captures rook" representation. + SquareDelta delta = (to > from ? DELTA_E : DELTA_W); + Square s = from; + + do s += delta; + while ( pos.piece_on(s) != piece_of_color_and_type(us, ROOK) + && relative_rank(us, s) == RANK_1); + + return relative_rank(us, s) == RANK_1 ? make_castle_move(from, s) : MOVE_NONE; + } + } + + return make_move(from, to); + } + // set_position() is called when Stockfish receives the "position" UCI // command. The input parameter is a UCIParser. It is assumed // that this parser has consumed the first token of the UCI command @@ -170,7 +241,7 @@ namespace { StateInfo st; while (up >> token) { - move = move_from_uci(pos, token); + move = parse_uci_move(pos, token); pos.do_setup_move(move, st); } // Our StateInfo st is about going out of scope so copy @@ -269,7 +340,7 @@ namespace { { int numOfMoves = 0; while (up >> token) - searchMoves[numOfMoves++] = move_from_uci(pos, token); + searchMoves[numOfMoves++] = parse_uci_move(pos, token); searchMoves[numOfMoves] = MOVE_NONE; }