updates NEWS, Changelog, DIFFSTAT and SHORTLOG
[xboard.git] / moves.c
diff --git a/moves.c b/moves.c
index 3205d2f..2f6a706 100644 (file)
--- a/moves.c
+++ b/moves.c
@@ -934,11 +934,14 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure,
                if(gameInfo.variant == VariantShogi) goto WhiteGold;
             case SHOGI (PROMO BlackPawn):
                if(gameInfo.variant == VariantShogi) goto BlackGold;
+            case SHOGI WhiteAxe:
+            case SHOGI BlackAxe:
                SlideVertical(board, flags, rf, ff, callback, closure);
                break;
 
             case SHOGI (PROMO WhiteKnight):
                if(gameInfo.variant == VariantShogi) goto WhiteGold;
+            case SHOGI WhiteClaw:
             case SHOGI BlackDrunk:
             case SHOGI BlackAlfil:
                Ferz(board, flags, rf, ff, callback, closure);
@@ -948,6 +951,7 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure,
 
             case SHOGI (PROMO BlackKnight):
                if(gameInfo.variant == VariantShogi) goto BlackGold;
+            case SHOGI BlackClaw:
             case SHOGI WhiteDrunk:
             case SHOGI WhiteAlfil:
                Ferz(board, flags, rf, ff, callback, closure);
@@ -982,6 +986,14 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure,
 
             case WhiteWazir:
             case BlackWazir:
+               if(gameInfo.variant == VariantXiangqi) {
+                   int palace = (piece == WhiteWazir ? 1 : BOARD_HEIGHT-2); // Palace center
+                   if(ff <= BOARD_WIDTH/2 && !SameColor(board[rf][ff+1], piece)) callback(board, flags, NormalMove, rf, ff, rf, ff+1, closure);
+                   if(ff >= BOARD_WIDTH/2 && !SameColor(board[rf][ff-1], piece)) callback(board, flags, NormalMove, rf, ff, rf, ff-1, closure);
+                   if(rf >= palace && !SameColor(board[rf-1][ff], piece)) callback(board, flags, NormalMove, rf, ff, rf-1, ff, closure);
+                   if(rf <= palace && !SameColor(board[rf+1][ff], piece)) callback(board, flags, NormalMove, rf, ff, rf+1, ff, closure);
+                   break;
+               }
                Wazir(board, flags, rf, ff, callback, closure);
                break;
 
@@ -1101,19 +1113,16 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure,
             /* Make Dragon-King Dababba & Rook-like outside Shogi, for better disambiguation in variant Fairy */
            case WhiteDragon:
            case BlackDragon:
-              if(gameInfo.variant == VariantChuChess) goto DragonKing;
+              if(gameInfo.variant == VariantChuChess || gameInfo.variant == VariantSpartan) goto DragonKing;
               for (d = 0; d <= 1; d++) // Dababba moves that Rook cannot do
                 for (s = -2; s <= 2; s += 4) {
                      rt = rf + s * d;
                      ft = ff + s * (1 - d);
                       if (rt < 0 || rt >= BOARD_HEIGHT || ft < BOARD_LEFT || ft >= BOARD_RGHT) continue;
-                      if (board[rf+rt>>1][ff+ft>>1] == EmptySquare && gameInfo.variant != VariantSpartan) continue;
+                      if (board[rf+rt>>1][ff+ft>>1] == EmptySquare) continue;
                      if (SameColor(board[rf][ff], board[rt][ft])) continue;
                      callback(board, flags, NormalMove, rf, ff, rt, ft, closure);
                  }
-              if(gameInfo.variant == VariantSpartan) // in Spartan Chess restrict range to modern Dababba
-               Wazir(board, flags, rf, ff, callback, closure);
-             else
                Rook(board, flags, rf, ff, callback, closure);
               break;
 
@@ -1138,6 +1147,19 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure,
                    Knight(board, flags, rf, ff, callback, closure);
                break;
 
+            case WhiteTower:
+            case BlackTower:
+                for (d = 0; d <= 1; d++) // Dababba moves
+                  for (s = -2; s <= 2; s += 4) {
+                     rt = rf + s * d;
+                     ft = ff + s * (1 - d);
+                      if (rt < 0 || rt >= BOARD_HEIGHT || ft < BOARD_LEFT || ft >= BOARD_RGHT) continue;
+                     if (SameColor(board[rf][ff], board[rt][ft])) continue;
+                     callback(board, flags, NormalMove, rf, ff, rt, ft, closure);
+                 }
+               Wazir(board, flags, rf, ff, callback, closure);
+               break;
+
             /* Shogi Rooks are ordinary Rooks */
             case SHOGI WhiteRook:
             case SHOGI BlackRook:
@@ -1179,6 +1201,12 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure,
 
             case WhiteFerz:
             case BlackFerz:
+               if(gameInfo.variant == VariantXiangqi && ff != BOARD_WIDTH>>1) {
+                   int rt = (piece == BlackFerz ? BOARD_HEIGHT-2 : 1);
+                   int ft = BOARD_WIDTH>>1;
+                   if(!SameColor(board[rf][ff], board[rt][ft]))
+                       callback(board, flags, NormalMove, rf, ff, rt, ft, closure);
+               } else
                 /* [HGM] support Shatranj pieces */
                Ferz(board, flags, rf, ff, callback, closure);
                break;
@@ -1270,8 +1298,8 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure,
               }
               break;
 
-            case SHOGI WhiteFalcon:
-            case SHOGI BlackFalcon:
+            case SHOGI WhiteDagger:
+            case SHOGI BlackDagger:
             case SHOGI WhitePDagger:
             case SHOGI BlackPDagger:
                SlideSideways(board, flags, rf, ff, callback, closure);
@@ -1287,24 +1315,26 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure,
                if(gameInfo.variant == VariantShogi) goto WhiteGold;
             case SHOGI (PROMO BlackFerz):
                if(gameInfo.variant == VariantShogi) goto BlackGold;
+            case SHOGI WhiteSword:
+            case SHOGI BlackSword:
             case SHOGI WhitePSword:
             case SHOGI BlackPSword:
                SlideVertical(board, flags, rf, ff, callback, closure);
                StepSideways(board, flags, rf, ff, callback, closure);
                break;
 
-            case SHOGI WhiteUnicorn:
-            case SHOGI BlackUnicorn:
+            case SHOGI WhiteCat:
+            case SHOGI BlackCat:
                Ferz(board, flags, rf, ff, callback, closure);
                StepVertical(board, flags, rf, ff, callback, closure);
                break;
 
-            case SHOGI WhiteMan:
+            case SHOGI WhiteCopper:
                StepDiagForward(board, flags, rf, ff, callback, closure);
                StepVertical(board, flags, rf, ff, callback, closure);
                break;
 
-            case SHOGI BlackMan:
+            case SHOGI BlackCopper:
                StepDiagBackward(board, flags, rf, ff, callback, closure);
                StepVertical(board, flags, rf, ff, callback, closure);
                break;
@@ -1321,7 +1351,7 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure,
                SlideVertical(board, flags, rf, ff, callback, closure);
                break;
 
-            case SHOGI WhiteCat:
+            case SHOGI WhiteUnicorn:
                Sting(board, flags, rf, ff, 1, 0, callback, closure);
                callback(board, flags, NormalMove, rf, ff, rf, ff, closure);
                if(killX >= 0) break;
@@ -1330,7 +1360,7 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure,
                SlideBackward(board, flags, rf, ff, callback, closure);
                break;
 
-            case SHOGI BlackCat:
+            case SHOGI BlackUnicorn:
                Sting(board, flags, rf, ff, -1, 0, callback, closure);
                callback(board, flags, NormalMove, rf, ff, rf, ff, closure);
                if(killX >= 0) break;
@@ -1339,7 +1369,7 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure,
                SlideForward(board, flags, rf, ff, callback, closure);
                break;
 
-            case SHOGI WhiteDagger:
+            case SHOGI WhiteFalcon:
                Sting(board, flags, rf, ff, 1,  1, callback, closure);
                Sting(board, flags, rf, ff, 1, -1, callback, closure);
                callback(board, flags, NormalMove, rf, ff, rf, ff, closure);
@@ -1348,7 +1378,7 @@ GenPseudoLegal (Board board, int flags, MoveCallback callback, VOIDSTAR closure,
                SlideDiagBackward(board, flags, rf, ff, callback, closure);
                break;
 
-            case SHOGI BlackDagger:
+            case SHOGI BlackFalcon:
                Sting(board, flags, rf, ff, -1,  1, callback, closure);
                Sting(board, flags, rf, ff, -1, -1, callback, closure);
                callback(board, flags, NormalMove, rf, ff, rf, ff, closure);
@@ -1705,6 +1735,8 @@ CheckTest (Board board, int flags, int rf, int ff, int rt, int ft, int enPassant
        }
     }
 
+    if(PieceToChar(king) == '.') return 0; // never in check if the royal piece does not participate
+
     if (rt >= 0) {
        if (enPassant) {
            captured = board[rf][ft];
@@ -2047,7 +2079,7 @@ DisambiguateCallback (Board board, int flags, ChessMove kind, int rf, int ff, in
     // [HGM] wild: for wild-card pieces rt and rf are dummies
     if(piece == WhiteFalcon || piece == BlackFalcon ||
        piece == WhiteCobra  || piece == BlackCobra)
-        wildCard = TRUE;
+        wildCard = !pieceDefs; // no wildcards when engine defined pieces
 
     if ((cl->pieceIn == EmptySquare || cl->pieceIn == board[rf][ff]
          || PieceToChar(board[rf][ff]) == '~'
@@ -2131,8 +2163,13 @@ Disambiguate (Board board, int flags, DisambiguateClosure *closure)
            return;
          }
        }
-    } else if(pieceDefs && closure->count > 1) { // [HGM] gen: move is ambiguous under engine-defined rules
+    } else if(pieceDefs && closure->count > 1 && closure->rtIn >=0) { // [HGM] gen: move is ambiguous under engine-defined rules (and not one-click)
        DisambiguateClosure spare = *closure;
+        if(gameInfo.variant == VariantXiangqi && closure->pieceIn == EmptySquare && closure->ffIn < 0) {
+            closure->ffIn = closure->ftIn; //closure->pieceIn = (flags & 1 ? BlackPawn : WhitePawn); // forward Pawn push has priority
+            Disambiguate(board, flags, closure);
+            return;
+        }
        pieceDefs = FALSE; spare.count = 0;     // See if the (erroneous) built-in rules would resolve that
         GenLegal(board, flags, DisambiguateCallback, (VOIDSTAR) &spare, closure->pieceIn);
        if(spare.count == 1) *closure = spare;  // It does, so use those in stead (game from file saved before gen patch?)