Fix Seirawan gating at Rook square in PGN castling moves v4.9.x
authorH.G.Muller <hgm@hgm-xboard.(none)>
Wed, 8 Nov 2017 10:30:05 +0000 (11:30 +0100)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Wed, 8 Nov 2017 10:30:05 +0000 (11:30 +0100)
The 'reverse gatings' were written as RxK also in PGN, which was ugly.
Now a file disambiguator behind the ID of the gated piece is used for
all castling gatings (also those at the King square). On input omission
of the disambiguator defaults to King square.

moves.c
parser.c

diff --git a/moves.c b/moves.c
index 6461583..a6b066b 100644 (file)
--- a/moves.c
+++ b/moves.c
@@ -2401,9 +2401,9 @@ CoordsToAlgebraic (Board board, int flags, int rf, int ff, int rt, int ft, int p
             ((ff == BOARD_WIDTH>>1 && (ft == BOARD_LEFT+2 || ft == BOARD_RGHT-2)) ||
              (ff == (BOARD_WIDTH-1)>>1 && (ft == BOARD_LEFT+1 || ft == BOARD_RGHT-3)))) {
             if(ft==BOARD_LEFT+1 || ft==BOARD_RGHT-2)
-             snprintf(out, MOVE_LEN, "O-O%c%c", promoChar ? '/' : 0, ToUpper(promoChar));
+             snprintf(out, MOVE_LEN, "O-O%c%c%c", promoChar ? '/' : 0, ToUpper(promoChar), ff + AAA);
             else
-             snprintf(out, MOVE_LEN, "O-O-O%c%c", promoChar ? '/' : 0, ToUpper(promoChar));
+             snprintf(out, MOVE_LEN, "O-O-O%c%c%c", promoChar ? '/' : 0, ToUpper(promoChar), ff + AAA);
 
            /* This notation is always unambiguous, unless there are
               kings on both the d and e files, with "wild castling"
@@ -2478,8 +2478,15 @@ CoordsToAlgebraic (Board board, int flags, int rf, int ff, int rt, int ft, int p
             *outp++ = ToUpper(promoChar);
         }
         else if (gameInfo.variant == VariantSChess && promoChar) { // and in S-Chess we have gating
+            ChessSquare victim = board[rt][ft];
+            if(piece == WhiteRook && victim == WhiteKing ||
+               piece == BlackRook && victim == BlackKing) {
+                strncpy(out, "O-O-O", MOVE_LEN);
+                outp = out + 3 + 2*(ft > ff);
+            }
             *outp++ = '/';
             *outp++ = ToUpper(promoChar);
+            if(out[0] == 'O') *outp++ = ff + AAA;
         }
        *outp = NULLCHAR;
         return cl.kind;
index 0938242..797a40c 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -642,9 +642,12 @@ badMove:// we failed to find algebraic move
                    Match("OO", p) || Match("oo", p) || Match("00", p)) castlingType = 1;
            if(castlingType) { //code from old parser, collapsed for both castling types, and streamlined a bit
                int rf, ff, rt, ft; ChessSquare king;
-               char promo=NULLCHAR;
+               char promo=NULLCHAR, gate = 0;
 
-               if(gameInfo.variant == VariantSChess) promo = PromoSuffix(p);
+               if(gameInfo.variant == VariantSChess) {
+                   promo = PromoSuffix(p);
+                   if(promo && **p >= 'a' && **p < AAA + BOARD_RGHT) gate = *(*p)++;
+               }
 
                if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */
 
@@ -680,6 +683,12 @@ badMove:// we failed to find algebraic move
                    if (appData.debugMode) fprintf(debugFP, "Parser FRC (type=%d) %d %d\n", castlingType, ff, ft);
                    if(ff == NoRights || ft == NoRights) return ImpossibleMove;
                }
+               if(gate) { // gating disambiguator present
+                   if(gate != ff + AAA) {
+                       int h = ft; ft = ff; ff = h; // reverse for gating at Rook square
+                       if(gate != AAA + initialRights[castlingType+(wom?-1:2)]) return ImpossibleMove;
+                   }
+               }
                sprintf(currentMoveString, "%c%c%c%c%c",ff+AAA,rf+ONE,ft+AAA,rt+ONE,promo);
                if (appData.debugMode) fprintf(debugFP, "(%d-type) castling %d %d\n", castlingType, ff, ft);