]> git.sesse.net Git - stockfish/blobdiff - src/move.cpp
Micro-optimize castling handling in do_move()
[stockfish] / src / move.cpp
index 96215e82478e7348654c1ce9ad5dd1e84946d874..0a620781ce1be0a85eb9929bbf60691b504a7f42 100644 (file)
@@ -59,14 +59,15 @@ const string move_to_uci(Move m, bool chess960) {
       return from == SQ_E1 ? "e1c1" : "e8c8";
 
   if (move_is_promotion(m))
-      promotion = char(tolower(piece_type_to_char(move_promotion_piece(m))));
+      promotion = char(tolower(piece_type_to_char(promotion_piece_type(m))));
 
   return square_to_string(from) + square_to_string(to) + promotion;
 }
 
 
 /// move_from_uci() takes a position and a string representing a move in
-/// simple coordinate notation and returns an equivalent Move.
+/// simple coordinate notation and returns an equivalent Move if any.
+/// Moves are guaranteed to be legal.
 
 Move move_from_uci(const Position& pos, const string& str) {
 
@@ -90,8 +91,9 @@ const string move_to_san(Position& pos, Move m) {
   assert(pos.is_ok());
   assert(move_is_ok(m));
 
-  MoveStack mlist[MAX_MOVES];
-  Square from = move_from(m);
+  Bitboard attackers;
+  bool ambiguousMove, ambiguousFile, ambiguousRank;
+  Square sq, from = move_from(m);
   Square to = move_to(m);
   PieceType pt = pos.type_of_piece_on(from);
   string san;
@@ -112,30 +114,34 @@ const string move_to_san(Position& pos, Move m) {
       {
           san = piece_type_to_char(pt);
 
-          // Collect all legal moves of piece type 'pt' with destination 'to'
-          MoveStack* last = generate<MV_LEGAL>(pos, mlist);
-          int f = 0, r = 0;
-
-          for (MoveStack* cur = mlist; cur != last; cur++)
-              if (   move_to(cur->move) == to
-                  && pos.type_of_piece_on(move_from(cur->move)) == pt)
-              {
-                  if (square_file(move_from(cur->move)) == square_file(from))
-                      f++;
-
-                  if (square_rank(move_from(cur->move)) == square_rank(from))
-                      r++;
-              }
-
-          assert(f > 0 && r > 0);
-
           // Disambiguation if we have more then one piece with destination 'to'
-          if (f == 1 && r > 1)
-              san += file_to_char(square_file(from));
-          else if (f > 1 && r == 1)
-              san += rank_to_char(square_rank(from));
-          else if (f > 1 && r > 1)
-              san += square_to_string(from);
+          // note that for pawns is not needed because starting file is explicit.
+          attackers = pos.attackers_to(to) & pos.pieces(pt, pos.side_to_move());
+          clear_bit(&attackers, from);
+          ambiguousMove = ambiguousFile = ambiguousRank = false;
+
+          while (attackers)
+          {
+              sq = pop_1st_bit(&attackers);
+
+              if (square_file(sq) == square_file(from))
+                  ambiguousFile = true;
+
+              if (square_rank(sq) == square_rank(from))
+                  ambiguousRank = true;
+
+              ambiguousMove = true;
+          }
+
+          if (ambiguousMove)
+          {
+              if (!ambiguousFile)
+                  san += file_to_char(square_file(from));
+              else if (!ambiguousRank)
+                  san += rank_to_char(square_rank(from));
+              else
+                  san += square_to_string(from);
+          }
       }
 
       if (pos.move_is_capture(m))
@@ -151,15 +157,15 @@ const string move_to_san(Position& pos, Move m) {
       if (move_is_promotion(m))
       {
           san += '=';
-          san += piece_type_to_char(move_promotion_piece(m));
+          san += piece_type_to_char(promotion_piece_type(m));
       }
   }
 
-  // The move gives check? We don't use pos.move_is_check() here
+  // The move gives check? We don't use pos.move_gives_check() here
   // because we need to test for a mate after the move is done.
   StateInfo st;
   pos.do_move(m, st);
-  if (pos.is_check())
+  if (pos.in_check())
       san += pos.is_mate() ? "#" : "+";
   pos.undo_move(m);