Also do dual-royal test in variant shogi
[xboard.git] / moves.c
diff --git a/moves.c b/moves.c
index 54f46c8..4a097df 100644 (file)
--- a/moves.c
+++ b/moves.c
@@ -265,10 +265,13 @@ void
 MovesFromString (Board board, int flags, int f, int r, int tx, int ty, int angle, char *desc, MoveCallback cb, VOIDSTAR cl)
 {
     char buf[80], *p = desc, *atom = NULL;
-    int mine, his, dir, bit, occup, i;
+    int mine, his, dir, bit, occup, i, promoRank = -1;
+    ChessMove promo= NormalMove; ChessSquare pc = board[r][f];
     if(flags & F_WHITE_ON_MOVE) his = 2, mine = 1; else his = 1, mine = 2;
+    if(pc == WhitePawn || pc == WhiteLance) promo = WhitePromotion, promoRank = BOARD_HEIGHT-1; else
+    if(pc == BlackPawn || pc == BlackLance) promo = BlackPromotion, promoRank = 0;
     while(*p) {                  // more moves to go
-       int expo = 1, dx, dy, x, y, mode, dirSet, ds2, retry=0, initial=0, jump=1, skip = 0, all = 0;
+       int expo = 1, dx, dy, x, y, mode, dirSet, ds2=0, retry=0, initial=0, jump=1, skip = 0, all = 0;
        char *cont = NULL;
        if(*p == 'i') initial = 1, desc = ++p;
        while(islower(*p)) p++;  // skip prefixes
@@ -434,7 +437,7 @@ MovesFromString (Board board, int flags, int f, int r, int tx, int ty, int angle
                    break;
                }
                if(mode & 16 && (board[y][x] == WhiteKing || board[y][x] == BlackKing)) break; // tame piece, cannot capture royal
-               if(occup & mode) cb(board, flags, NormalMove, r, f, y, x, cl);    // allowed, generate
+               if(occup & mode) cb(board, flags, y == promoRank ? promo : NormalMove, r, f, y, x, cl); // allowed, generate
                if(occup != 4) break; // not valid transit square
            } while(--i);
          }
@@ -1610,14 +1613,16 @@ CheckTest (Board board, int flags, int rf, int ff, int rt, int ft, int enPassant
     CheckTestClosure cl;
     ChessSquare king = flags & F_WHITE_ON_MOVE ? WhiteKing : BlackKing;
     ChessSquare captured = EmptySquare, ep=0, trampled=0;
+    int saveKill = killX;
     /*  Suppress warnings on uninitialized variables    */
 
     if(gameInfo.variant == VariantXiangqi)
         king = flags & F_WHITE_ON_MOVE ? WhiteWazir : BlackWazir;
     if(gameInfo.variant == VariantKnightmate)
         king = flags & F_WHITE_ON_MOVE ? WhiteUnicorn : BlackUnicorn;
-    if(gameInfo.variant == VariantChu) { // strictly speaking this is not needed, as Chu officially has no check
+    if(gameInfo.variant == VariantChu || gameInfo.variant == VariantShogi) { // strictly speaking this is not needed, as Chu officially has no check
        int r, f, k = king, royals=0, prince = flags & F_WHITE_ON_MOVE ? WhiteMonarch : BlackMonarch;
+       if(gameInfo.variant == VariantShogi) prince -= 11;                   // White/BlackFalcon
        for(r=0; r<BOARD_HEIGHT; r++) for(f=BOARD_LEFT; f<BOARD_RGHT; f++) {
            if(board[r][f] == k || board[r][f] == prince) {
                if(++royals > 1) return FALSE; // no check if we have two royals (ignores double captureby Lion!)
@@ -1632,7 +1637,7 @@ CheckTest (Board board, int flags, int rf, int ff, int rt, int ft, int enPassant
            board[rf][ft] = EmptySquare;
        } else {
            captured = board[rt][ft];
-           if(killX >= 0) { trampled = board[killY][killX]; board[killY][killX] = EmptySquare; }
+           if(killX >= 0) { trampled = board[killY][killX]; board[killY][killX] = EmptySquare; killX = -1; }
        }
        if(rf == DROP_RANK) board[rt][ft] = ff; else { // [HGM] drop
            board[rt][ft] = board[rf][ff];
@@ -1680,7 +1685,7 @@ CheckTest (Board board, int flags, int rf, int ff, int rt, int ft, int enPassant
            board[rf][ft] = captured;
            board[rt][ft] = EmptySquare;
        } else {
-           if(killX >= 0) board[killY][killX] = trampled;
+           if(saveKill >= 0) board[killY][killX] = trampled, killX = saveKill;
            board[rt][ft] = captured;
        }
        board[EP_STATUS] = ep;