No disambiguation for elephants/advisors
authorFabian Fichter <ianfab@users.noreply.github.com>
Sun, 5 Apr 2020 16:02:52 +0000 (18:02 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Sun, 5 Apr 2020 16:02:52 +0000 (18:02 +0200)
Only use disambiguation in WXF notation if the move is really ambiguous.

src/pyffish.cpp
test.py

index 9a45089..751dd1a 100644 (file)
@@ -143,7 +143,17 @@ Disambiguation disambiguation_level(const Position& pos, Move m, Notation n) {
 
     // Xiangqi uses either file disambiguation or +/- if two pieces on file
     if (n == NOTATION_XIANGQI_WXF)
-        return popcount(file_bb(from) & pos.pieces(us, pt)) == 2 ? RANK_DISAMBIGUATION : FILE_DISAMBIGUATION;
+    {
+        // Disambiguate by rank (+/-) if target square of other piece is valid
+        if (popcount(pos.pieces(us, pt) & file_bb(from)) == 2)
+        {
+            Square otherFrom = lsb((pos.pieces(us, pt) & file_bb(from)) ^ from);
+            Square otherTo = otherFrom + Direction(to) - Direction(from);
+            if (is_ok(otherTo) && (pos.board_bb(us, pt) & otherTo))
+                return RANK_DISAMBIGUATION;
+        }
+        return FILE_DISAMBIGUATION;
+    }
 
     // Pawn captures always use disambiguation
     if ((n == NOTATION_SAN || n == NOTATION_LAN) && pt == PAWN && pos.capture(m) && from != to)
diff --git a/test.py b/test.py
index 6b6a93c..6083455 100644 (file)
--- a/test.py
+++ b/test.py
@@ -306,6 +306,15 @@ class TestPyffish(unittest.TestCase):
         result = sf.get_san("xiangqi", XIANGQI, "h3h5")
         self.assertEqual(result, "Ch5")
 
+        # skip disambiguation for elephants and advisors, but not for pieces that require it
+        fen = "rnbakabnr/9/1c5c1/p1p1p1p1p/9/1NB6/P1P1P1P1P/1C1A3C1/9/RNBAK21R w - - 0 1"
+        result = sf.get_san("xiangqi", fen, "c5e3", False, sf.NOTATION_XIANGQI_WXF)
+        self.assertEqual(result, "E7-5")
+        result = sf.get_san("xiangqi", fen, "d1e2", False, sf.NOTATION_XIANGQI_WXF)
+        self.assertEqual(result, "A6+5")
+        result = sf.get_san("xiangqi", fen, "b5c7", False, sf.NOTATION_XIANGQI_WXF)
+        self.assertEqual(result, "H++7")
+
         # Tandem pawns
         fen = "rnbakabnr/9/1c5c1/p1p1P1p1p/4P4/9/P3P3P/1C5C1/9/RNBAKABNR w - - 0 1"
         result = sf.get_san("xiangqi", fen, "e7d7", False, sf.NOTATION_XIANGQI_WXF)