Prevent transmission of spurious promo char to other engine
[xboard.git] / moves.c
diff --git a/moves.c b/moves.c
index 663660c..545a09c 100644 (file)
--- a/moves.c
+++ b/moves.c
@@ -5,7 +5,7 @@
  * Massachusetts.
  *
  * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,
- * 2007, 2008, 2009 Free Software Foundation, Inc.
+ * 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
  *
  * Enhancements Copyright 2005 Alessandro Scotti
  *
@@ -144,6 +144,7 @@ char pieceToChar[] = {
                         'p', 'n', 'b', 'r', 'q', 'f', 'e', 'a', 'c', 'w', 'm', 
                         'o', 'h', 'i', 'j', 'g', 'd', 'v', 'l', 's', 'u', 'k', 
                         'x' };
+char pieceNickName[EmptySquare];
 
 char PieceToChar(p)
      ChessSquare p;
@@ -167,6 +168,8 @@ ChessSquare CharToPiece(c)
 {
      int i;
      for(i=0; i< (int) EmptySquare; i++)
+          if(pieceNickName[i] == c) return (ChessSquare) i;
+     for(i=0; i< (int) EmptySquare; i++)
           if(pieceToChar[i] == c) return (ChessSquare) i;
      return EmptySquare;
 }
@@ -177,7 +180,7 @@ ChessMove PromoCharToMoveType(whiteOnMove, promoChar)
 {      /* [HGM] made dependent on CharToPiece to alow alternate piece letters */
        ChessSquare piece = CharToPiece(whiteOnMove ? ToUpper(promoChar) : ToLower(promoChar) );
 
-
+       if(promoChar == '=') return whiteOnMove ? WhiteNonPromotion : BlackNonPromotion;
        if(promoChar == NULLCHAR) return NormalMove;
 
        switch(piece) {
@@ -263,6 +266,7 @@ void GenPseudoLegal(board, flags, callback, closure)
     int rf, ff;
     int i, j, d, s, fs, rs, rt, ft, m;
     int epfile = (signed char)board[EP_STATUS]; // [HGM] gamestate: extract ep status from board
+    int promoRank = gameInfo.variant == VariantMakruk ? 3 : 1;
 
     for (rf = 0; rf < BOARD_HEIGHT; rf++) 
       for (ff = BOARD_LEFT; ff < BOARD_RGHT; ff++) {
@@ -306,7 +310,7 @@ void GenPseudoLegal(board, flags, callback, closure)
               }
               if (rf < BOARD_HEIGHT-1 && board[rf + 1][ff] == EmptySquare) {
                  callback(board, flags,
-                          rf == BOARD_HEIGHT-2 ? WhitePromotionQueen : NormalMove,
+                          rf >= BOARD_HEIGHT-1-promoRank ? WhitePromotionQueen : NormalMove,
                           rf, ff, rf + 1, ff, closure);
              }
              if (rf == 1 && board[2][ff] == EmptySquare &&
@@ -321,7 +325,7 @@ void GenPseudoLegal(board, flags, callback, closure)
                      ((flags & F_KRIEGSPIEL_CAPTURE) ||
                       BlackPiece(board[rf + 1][ff + s]))) {
                      callback(board, flags, 
-                              rf == BOARD_HEIGHT-2 ? WhitePromotionQueen : NormalMove,
+                              rf >= BOARD_HEIGHT-1-promoRank ? WhitePromotionQueen : NormalMove,
                               rf, ff, rf + 1, ff + s, closure);
                  }
                  if (rf == BOARD_HEIGHT-4) {
@@ -356,7 +360,7 @@ void GenPseudoLegal(board, flags, callback, closure)
               }
              if (rf > 0 && board[rf - 1][ff] == EmptySquare) {
                  callback(board, flags, 
-                          rf == 1 ? BlackPromotionQueen : NormalMove,
+                          rf <= promoRank ? BlackPromotionQueen : NormalMove,
                           rf, ff, rf - 1, ff, closure);
              }
              if (rf == BOARD_HEIGHT-2 && board[BOARD_HEIGHT-3][ff] == EmptySquare &&
@@ -371,7 +375,7 @@ void GenPseudoLegal(board, flags, callback, closure)
                      ((flags & F_KRIEGSPIEL_CAPTURE) ||
                       WhitePiece(board[rf - 1][ff + s]))) {
                      callback(board, flags, 
-                              rf == 1 ? BlackPromotionQueen : NormalMove,
+                              rf <= promoRank ? BlackPromotionQueen : NormalMove,
                               rf, ff, rf - 1, ff + s, closure);
                  }
                  if (rf == 3) {
@@ -611,6 +615,8 @@ void GenPseudoLegal(board, flags, callback, closure)
 
             /* Shogi Pawn and Silver General: first the Pawn move,    */
             /* then the General continues like a Ferz                 */
+            case WhiteMan:
+                if(gameInfo.variant != VariantMakruk) goto commoner;
             case SHOGI WhitePawn:
             case SHOGI WhiteFerz:
                   if (rf < BOARD_HEIGHT-1 &&
@@ -620,6 +626,8 @@ void GenPseudoLegal(board, flags, callback, closure)
               if(piece != SHOGI WhitePawn) goto finishSilver;
               break;
 
+            case BlackMan:
+                if(gameInfo.variant != VariantMakruk) goto commoner;
             case SHOGI BlackPawn:
             case SHOGI BlackFerz:
                   if (rf > 0 &&
@@ -647,8 +655,7 @@ void GenPseudoLegal(board, flags, callback, closure)
            case WhiteSilver:
            case BlackSilver:
                m++; // [HGM] superchess: use for Centaur
-            case WhiteMan:
-            case BlackMan:
+            commoner:
             case SHOGI WhiteKing:
             case SHOGI BlackKing:
            case WhiteKing:
@@ -1090,7 +1097,7 @@ ChessMove LegalityTest(board, flags, rf, ff, rt, ft, promoChar)
                          piece == WhiteKnight && rt > BOARD_HEIGHT-3) /* promotion mandatory */
                              cl.kind = promoChar == '=' ? IllegalMove : WhitePromotionKnight;
                     else /* promotion optional, default is promote */
-                             cl.kind = promoChar == '=' ? NormalMove  : WhitePromotionQueen;
+                             cl.kind = promoChar == '=' ? WhiteNonPromotion : WhitePromotionQueen;
                    
                 } else cl.kind = (promoChar == NULLCHAR || promoChar == 'x' || promoChar == '=') ?
                                             NormalMove : IllegalMove;
@@ -1100,7 +1107,7 @@ ChessMove LegalityTest(board, flags, rf, ff, rt, ft, promoChar)
                          piece == BlackKnight && rt < 2 ) /* promotion obligatory */
                              cl.kind = promoChar == '=' ? IllegalMove : BlackPromotionKnight;
                     else /* promotion optional, default is promote */
-                             cl.kind = promoChar == '=' ? NormalMove  : BlackPromotionQueen;
+                             cl.kind = promoChar == '=' ? BlackNonPromotion : BlackPromotionQueen;
 
                 } else cl.kind = (promoChar == NULLCHAR || promoChar == 'x' || promoChar == '=') ?
                                             NormalMove : IllegalMove;
@@ -1219,12 +1226,16 @@ void DisambiguateCallback(board, flags, kind, rf, ff, rt, ft, closure)
        (cl->ftIn == -1 || cl->ftIn == ft || wildCard)) {
 
        cl->count++;
-        cl->piece = board[rf][ff];
-       cl->rf = rf;
-       cl->ff = ff;
-       cl->rt = wildCard ? cl->rtIn : rt;
-       cl->ft = wildCard ? cl->ftIn : ft;
-       cl->kind = kind;
+       if(cl->count == 1 || board[rt][ft] != EmptySquare) {
+         // [HGM] oneclick: if multiple moves, be sure we remember capture
+         cl->piece = board[rf][ff];
+         cl->rf = rf;
+         cl->ff = ff;
+         cl->rt = wildCard ? cl->rtIn : rt;
+         cl->ft = wildCard ? cl->ftIn : ft;
+         cl->kind = kind;
+       }
+       cl->captures += (board[cl->rt][cl->ft] != EmptySquare); // [HGM] oneclick: count captures
     }
 }
 
@@ -1235,7 +1246,7 @@ void Disambiguate(board, flags, closure)
 {
     int illegal = 0; char c = closure->promoCharIn;
 
-    closure->count = 0;
+    closure->count = closure->captures = 0;
     closure->rf = closure->ff = closure->rt = closure->ft = 0;
     closure->kind = ImpossibleMove;
     if (appData.debugMode) {
@@ -1276,7 +1287,7 @@ void Disambiguate(board, flags, closure)
                              closure->kind = c == '=' ? IllegalMove : WhitePromotionKnight;
                     else /* promotion optional, default is promote */
                              closure->kind = c == '=' ? NormalMove  : WhitePromotionQueen;
-                   
+                    if(c != '=') closure->promoCharIn = 'q';
                 } else closure->kind = (c == NULLCHAR || c == 'x' || c == '=') ?
                                             NormalMove : IllegalMove;
             } else {
@@ -1286,7 +1297,7 @@ void Disambiguate(board, flags, closure)
                              closure->kind = c == '=' ? IllegalMove : BlackPromotionKnight;
                     else /* promotion optional, default is promote */
                              closure->kind = c == '=' ? NormalMove  : BlackPromotionQueen;
-
+                    if(c != '=') closure->promoCharIn = 'q';
                 } else closure->kind = (c == NULLCHAR || c == 'x' || c == '=') ?
                                             NormalMove : IllegalMove;
             }