- Ambiguity move_ambiguity(Position &pos, Move m) {
- Square from, to;
- Piece pc;
-
- from = move_from(m);
- to = move_to(m);
- pc = pos.piece_on(from);
-
- // King moves are never ambiguous, because there is never two kings of
- // the same color.
- if(type_of_piece(pc) == KING)
- return AMBIGUITY_NONE;
-
- MovePicker mp = MovePicker(pos, false, MOVE_NONE, MOVE_NONE, MOVE_NONE,
- MOVE_NONE, OnePly);
- Move mv, moveList[8];
- int i, j, n;
-
- n = 0;
- while((mv = mp.get_next_move()) != MOVE_NONE)
- if(move_to(mv) == to && pos.piece_on(move_from(mv)) == pc
- && pos.move_is_legal(mv))
- moveList[n++] = mv;
- if(n == 1)
- return AMBIGUITY_NONE;
-
- j = 0;
- for(i = 0; i < n; i++)
- if(square_file(move_from(moveList[i])) == square_file(from))
- j++;
- if(j == 1)
- return AMBIGUITY_FILE;
-
- j = 0;
- for(i = 0; i < n; i++)
- if(square_rank(move_from(moveList[i])) == square_rank(from))
- j++;
- if(j == 1)
- return AMBIGUITY_RANK;
-
- return AMBIGUITY_BOTH;
+ Ambiguity move_ambiguity(const Position& pos, Move m) {
+
+ MoveStack mlist[MOVES_MAX], *last;
+ Move candidates[8];
+ Square from = move_from(m);
+ Square to = move_to(m);
+ Piece pc = pos.piece_on(from);
+ int matches = 0, f = 0, r = 0;
+
+ // If there is only one piece 'pc' then move cannot be ambiguous
+ if (pos.piece_count(pos.side_to_move(), type_of_piece(pc)) == 1)
+ return AMBIGUITY_NONE;
+
+ // Collect all legal moves of piece 'pc' with destination 'to'
+ last = generate<MV_LEGAL>(pos, mlist);
+ for (MoveStack* cur = mlist; cur != last; cur++)
+ if (move_to(cur->move) == to && pos.piece_on(move_from(cur->move)) == pc)
+ candidates[matches++] = cur->move;
+
+ if (matches == 1)
+ return AMBIGUITY_NONE;
+
+ for (int i = 0; i < matches; i++)
+ {
+ if (square_file(move_from(candidates[i])) == square_file(from))
+ f++;
+
+ if (square_rank(move_from(candidates[i])) == square_rank(from))
+ r++;
+ }
+
+ return f == 1 ? AMBIGUITY_FILE : r == 1 ? AMBIGUITY_RANK : AMBIGUITY_BOTH;