Process VariantMen PGN tag
authorH.G.Muller <hgm@hgm-xboard.(none)>
Sat, 6 Feb 2016 14:12:19 +0000 (15:12 +0100)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Sat, 6 Feb 2016 14:12:19 +0000 (15:12 +0100)
On loading a PGN game the VariantMen tag is now parsed, and the
move definitions are assigned to the mentioned pieces.
This only works when the pieceToCharTable is defined in advance!

backend.h
moves.c
pgntags.c

index 9f95098..594be72 100644 (file)
--- a/backend.h
+++ b/backend.h
@@ -218,6 +218,7 @@ int GetEngineLine P((char *nick, int engine));
 void AddGameToBook P((int always));
 void FlushBook P((void));
 char PieceToChar P((ChessSquare p));
+int LoadPieceDesc P((char *s));
 
 char *StrStr P((char *string, char *match));
 char *StrCaseStr P((char *string, char *match));
diff --git a/moves.c b/moves.c
index 1849fce..0b6b9b4 100644 (file)
--- a/moves.c
+++ b/moves.c
@@ -232,6 +232,38 @@ CollectPieceDescriptors ()
     return buf;
 }
 
+int
+LoadPieceDesc (char *s)
+{
+    ChessSquare piece;
+    static char suf[] = SUFFIXES;
+    char *r, *p, *q = s;
+    int ok = TRUE, promoted, c;
+    while(q && *s) {
+       p = s;
+       q = strchr(s, ';');
+       if(q) *q = 0, s = q+1;
+       if(*p == '+') promoted = 1, p++; else promoted = 0;
+       c = *p++;
+       if(!c) { ok = FALSE; continue; } // bad syntax
+       if(*p && (r = strchr(suf, *p))) c += 64*(r - suf + 1), p++;
+       if(*p++ != ':') { ok = FALSE; continue; } // bad syntax
+       if(!strcmp(p, "(null)")) continue; // handle bug in writing of XBoard 4.8.0
+        piece = CharToPiece(c);
+       if(piece >= EmptySquare) { ok = FALSE; continue; } // non-existent piece
+       if(promoted) {
+           piece = promoPartner[piece];
+           if(pieceToChar[piece] != '+') { ok = FALSE; continue; } // promoted form does not exist
+       }
+       ASSIGN(pieceDesc[piece], p);
+       if(piece < BlackPawn && (pieceToChar[WHITE_TO_BLACK piece] == pieceToChar[piece] || promoted)) {
+           ASSIGN(pieceDesc[WHITE_TO_BLACK piece], p);
+       }
+       pieceDefs = TRUE;
+    }
+    return ok;
+}
+
 // [HGM] gen: configurable move generation from Betza notation sent by engine.
 // Some notes about two-leg moves: GenPseudoLegal() works in two modes, depending on whether a 'kill-
 // square has been set: without one is generates all moves, and a global int legNr flags in bits 0 and 1
index b07f977..5b1ac77 100644 (file)
--- a/pgntags.c
+++ b/pgntags.c
@@ -118,9 +118,7 @@ ParsePGNTag (char *tag, GameInfo *gameInfo)
         if(*value && strcmp(value, engineVariant)) // keep current engine-defined variant if it matches
             gameInfo->variant = StringToVariant(value);
     } else if (StrCaseCmp(name, "VariantMen") == 0) {
-        /* for now ignore this tag, as we have no method yet */
-        /* for assigning the pieces to XBoard pictograms     */
-        success = TRUE;
+        success = LoadPieceDesc(value);
     } else if (StrCaseCmp(name, PGN_OUT_OF_BOOK) == 0) {
         /* [AS] Out of book annotation */
         success = StrSavePtr(value, &gameInfo->outOfBook) != NULL;