Move uci move parsing under san.cpp
authorMarco Costalba <mcostalba@gmail.com>
Sat, 8 Jan 2011 14:53:08 +0000 (15:53 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Sat, 8 Jan 2011 14:53:49 +0000 (15:53 +0100)
This partially reverts 1e7aaed8bc keeping the conversion
functions from/to move to uci string in the same file.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/san.cpp
src/san.h
src/search.cpp
src/uci.cpp

index 1eb59c32fb17bca173466a764d7e090710ab6ed5..5316236124c08289a6d18903699740d46103f89e 100644 (file)
@@ -53,6 +53,106 @@ namespace {
 //// Functions
 ////
 
+/// move_to_uci() converts a move to a string in coordinate notation
+/// (g1f3, a7a8q, etc.). The only special case is castling moves, where we
+/// print in the e1g1 notation in normal chess mode, and in e1h1 notation in
+/// Chess960 mode.
+
+const std::string move_to_uci(Move m, bool chess960) {
+
+  std::string str;
+  Square from = move_from(m);
+  Square to = move_to(m);
+
+  if (m == MOVE_NONE)
+      return "(none)";
+
+  if (m == MOVE_NULL)
+      return "0000";
+
+  if (move_is_short_castle(m) && !chess960)
+      return from == SQ_E1 ? "e1g1" : "e8g8";
+
+  if (move_is_long_castle(m) && !chess960)
+      return from == SQ_E1 ? "e1c1" : "e8c8";
+
+  str = square_to_string(from) + square_to_string(to);
+
+  if (move_is_promotion(m))
+      str += char(tolower(piece_type_to_char(move_promotion_piece(m))));
+
+  return str;
+}
+
+/// move_from_uci() takes a position and a string as input, and attempts to
+/// convert the string to a move, using simple coordinate notation (g1f3,
+/// a7a8q, etc.). This function is not robust, and expects that the input
+/// move is legal and correctly formatted.
+
+Move move_from_uci(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);
+}
+
+
 /// move_to_san() takes a position and a move as input, where it is assumed
 /// that the move is a legal move from the position. The return value is
 /// a string containing the move in short algebraic notation.
index e9b28b20a88fa2f6e96799bcb439283204734c2c..71aaabe24e7cec75f529e0fc3171268c3dc5cc83 100644 (file)
--- a/src/san.h
+++ b/src/san.h
@@ -36,6 +36,8 @@
 //// Prototypes
 ////
 
+extern const std::string move_to_uci(Move m, bool chess960);
+extern Move move_from_uci(const Position& pos, const std::string& str);
 extern const std::string move_to_san(Position& pos, Move m);
 extern Move move_from_san(const Position& pos, const std::string& str);
 extern const std::string line_to_san(const Position& pos, Move line[], int startColumn, bool breakLines);
index 9be9cccd52a68ee8c2939539cbc88f12a60eefde..28443b70ee6ee964cad05dd0ef7249f8915dfa3b 100644 (file)
@@ -170,8 +170,11 @@ namespace {
 
   // Overload operator << for moves to make it easier to print moves in
   // coordinate notation compatible with UCI protocol.
+  std::ostream& operator<<(std::ostream& os, Move m) {
 
-  std::ostream& operator<<(std::ostream& os, Move m);
+    bool chess960 = (os.iword(0) != 0); // See set960()
+    return os << move_to_uci(m, chess960);
+  }
 
 
   /// Adjustments
@@ -2717,35 +2720,4 @@ split_point_start: // At split points actual search starts from here
               }
   }
 
-  // Overload operator << to make it easier to print moves in coordinate notation
-  // (g1f3, a7a8q, etc.). The only special case is castling moves, where we
-  // print in the e1g1 notation in normal chess mode, and in e1h1 notation in
-  // Chess960 mode.
-
-  std::ostream& operator<<(std::ostream& os, Move m) {
-
-    Square from = move_from(m);
-    Square to = move_to(m);
-    bool chess960 = (os.iword(0) != 0); // See set960()
-
-    if (m == MOVE_NONE)
-        return os << "(none)";
-
-    if (m == MOVE_NULL)
-        return os << "0000";
-
-    if (move_is_short_castle(m) && !chess960)
-        return os << (from == SQ_E1 ? "e1g1" : "e8g8");
-
-    if (move_is_long_castle(m) && !chess960)
-        return os << (from == SQ_E1 ? "e1c1" : "e8c8");
-
-    os << square_to_string(from) << square_to_string(to);
-
-    if (move_is_promotion(m))
-        os << char(tolower(piece_type_to_char(move_promotion_piece(m))));
-
-    return os;
-  }
-
 } // namespace
index ae34043831cb19f39fa96fd7c9f677f7d68733a0..46cd39eaa5366b71bdfbb403e76a95ee5dd1b01e 100644 (file)
@@ -54,7 +54,6 @@ 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);
 }
 
 
@@ -134,75 +133,6 @@ 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
@@ -241,7 +171,7 @@ namespace {
     StateInfo st;
     while (up >> token)
     {
-        move = parse_uci_move(pos, token);
+        move = move_from_uci(pos, token);
         pos.do_setup_move(move, st);
     }
     // Our StateInfo st is about going out of scope so copy
@@ -340,7 +270,7 @@ namespace {
         {
             int numOfMoves = 0;
             while (up >> token)
-                searchMoves[numOfMoves++] = parse_uci_move(pos, token);
+                searchMoves[numOfMoves++] = move_from_uci(pos, token);
 
             searchMoves[numOfMoves] = MOVE_NONE;
         }