X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=125fd3de4590026beac1ae7e719841903414a149;hb=e921ccb3b79c9cfc5657e715eb50b5d9ed298db8;hp=e4e35508e40515d11922b0c591cbd0873144f95c;hpb=4ac8f856998e69684cb3465ffaead92a6a6ed9b1;p=xboard.git diff --git a/backend.c b/backend.c index e4e3550..125fd3d 100644 --- a/backend.c +++ b/backend.c @@ -5947,23 +5947,40 @@ SetUpShuffle (Board board, int number) } int -SetCharTable (char *table, const char * map) +ptclen (const char *s, char *escapes) +{ + int n = 0; + if(!*escapes) return strlen(s); + while(*s) n += (*s != ':' && !strchr(escapes, *s)), s++; + return n; +} + +int +SetCharTableEsc (unsigned char *table, const char * map, char * escapes) /* [HGM] moved here from winboard.c because of its general usefulness */ /* Basically a safe strcpy that uses the last character as King */ { int result = FALSE; int NrPieces; - if( map != NULL && (NrPieces=strlen(map)) <= (int) EmptySquare + if( map != NULL && (NrPieces=ptclen(map, escapes)) <= (int) EmptySquare && NrPieces >= 12 && !(NrPieces&1)) { - int i; /* [HGM] Accept even length from 12 to 34 */ + int i, j = 0; /* [HGM] Accept even length from 12 to 88 */ for( i=0; i<(int) EmptySquare; i++ ) table[i] = '.'; for( i=0; i= WhiteLion || PieceToChar(piece + 22) == '.') ? WhitePawn : WhiteLion; } else if(gameInfo.variant == VariantShogi) { - promotionZoneSize = BOARD_HEIGHT/3; + promotionZoneSize = BOARD_HEIGHT/3 +(BOARD_HEIGHT == 8); highestPromotingPiece = (int)WhiteAlfil; } else if(gameInfo.variant == VariantMakruk || gameInfo.variant == VariantGrand || gameInfo.variant == VariantChuChess) { promotionZoneSize = 3; @@ -7033,6 +7056,7 @@ UserMoveEvent(int fromX, int fromY, int toX, int toY, int promoChar) if(addToBookFlag) { // adding moves to book char buf[MSG_SIZ], move[MSG_SIZ]; CoordsToAlgebraic(boards[currentMove], PosFlags(currentMove), fromY, fromX, toY, toX, promoChar, move); + if(killX >= 0) snprintf(move, MSG_SIZ, "%c%dx%c%d-%c%d", fromX + AAA, fromY + ONE - '0', killX + AAA, killY + ONE - '0', toX + AAA, toY + ONE - '0'); snprintf(buf, MSG_SIZ, " 0.0%% 1 %s\n", move); AddBookMove(buf); addToBookFlag = FALSE; @@ -8672,7 +8696,12 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h if(machineMove[strlen(machineMove)-1] == ',') { // move ends in coma: non-final leg of composite move safeStrCpy(firstLeg, machineMove, 20); // just remember it for processing when second leg arrives return; - } else if(firstLeg[0]) { // there was a previous leg; + } + if(p = strchr(machineMove, ',')) { // we got both legs in one (happens on book move) + safeStrCpy(firstLeg, machineMove, 20); // kludge: fake we received the first leg earlier, and clip it off + safeStrCpy(machineMove, firstLeg + (p - machineMove) + 1, 20); + } + if(firstLeg[0]) { // there was a previous leg; // only support case where same piece makes two step char buf[20], *p = machineMove+1, *q = buf+1, f; safeStrCpy(buf, machineMove, 20); @@ -8907,7 +8936,7 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h if(appData.icsActive || forwardMostMove != 0 || cps != &first) return; *buf = NULLCHAR; if(sscanf(message, "setup (%s", buf) == 1) { - s = 8 + strlen(buf), buf[s-9] = NULLCHAR, SetCharTable(pieceToChar, buf); + s = 8 + strlen(buf), buf[s-9] = NULLCHAR, SetCharTableEsc(pieceToChar, buf, SUFFIXES); ASSIGN(appData.pieceToCharTable, buf); } dummy = sscanf(message+s, "%dx%d+%d_%s", &w, &h, &hand, varName); @@ -8918,7 +8947,7 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h appData.NrFiles = w; appData.NrRanks = h; appData.holdingsSize = hand; if(dummy == 4) gameInfo.variant = StringToVariant(varName); // parent variant InitPosition(1); // calls InitDrawingSizes to let new parameters take effect - if(*buf) SetCharTable(pieceToChar, buf); // do again, for it was spoiled by InitPosition + if(*buf) SetCharTableEsc(pieceToChar, buf, SUFFIXES); // do again, for it was spoiled by InitPosition startedFromSetupPosition = FALSE; } } @@ -8931,9 +8960,10 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h } if(sscanf(message, "piece %s %s", buf2, buf1) == 2) { ChessSquare piece = WhitePawn; - char *p=buf2; - if(*p == '+') piece = CHUPROMOTED WhitePawn, p++; - piece += CharToPiece(*p) - WhitePawn; + char *p=buf2, *q, *s = SUFFIXES, ID = *p; + if(*p == '+') piece = CHUPROMOTED WhitePawn, ID = *++p; + if(q = strchr(s, p[1])) ID += 64*(q - s + 1), p++; + piece += CharToPiece(ID) - WhitePawn; if(cps != &first || appData.testLegality && *engineVariant == NULLCHAR /* always accept definition of */ && piece != WhiteFalcon && piece != BlackFalcon /* wild-card pieces. */ && piece != WhiteCobra && piece != BlackCobra @@ -9068,7 +9098,7 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h return; } if(!strncmp(message, "highlight ", 10)) { - if(appData.testLegality && appData.markers) return; + if((appData.testLegality || *engineVariant) && appData.markers) return; MarkByFEN(message+10); // [HGM] alien: allow engine to mark board squares return; } @@ -12075,8 +12105,13 @@ LoadGameOneMove (ChessMove readAhead) if (appData.debugMode) fprintf(debugFP, "Parsed %s into IllegalMove %s\n", yy_text, currentMoveString); - fromX = currentMoveString[0] - AAA; - fromY = currentMoveString[1] - ONE; + if(currentMoveString[1] == '@') { + fromX = CharToPiece(WhiteOnMove(currentMove) ? ToUpper(currentMoveString[0]) : ToLower(currentMoveString[0])); + fromY = DROP_RANK; + } else { + fromX = currentMoveString[0] - AAA; + fromY = currentMoveString[1] - ONE; + } toX = currentMoveString[2] - AAA; toY = currentMoveString[3] - ONE; promoChar = currentMoveString[4]; @@ -12693,7 +12728,10 @@ LoadGame (FILE *f, int gameNumber, char *title, int useList) int numPGNTags = 0; int err, pos = -1; GameMode oldGameMode; - VariantClass oldVariant = gameInfo.variant; /* [HGM] PGNvariant */ + VariantClass v, oldVariant = gameInfo.variant; /* [HGM] PGNvariant */ + char oldName[MSG_SIZ]; + + safeStrCpy(oldName, engineVariant, MSG_SIZ); v = oldVariant; if (appData.debugMode) fprintf(debugFP, "LoadGame(): on entry, gameMode %d\n", gameMode); @@ -13051,6 +13089,10 @@ LoadGame (FILE *f, int gameNumber, char *title, int useList) StartChessProgram(&first); } InitChessProgram(&first, FALSE); + if(gameInfo.variant == VariantUnknown && *oldName) { + safeStrCpy(engineVariant, oldName, MSG_SIZ); + gameInfo.variant = v; + } SendToProgram("force\n", &first); if (startedFromSetupPosition) { SendBoard(&first, forwardMostMove); @@ -13243,8 +13285,8 @@ LoadPosition (FILE *f, int positionNumber, char *title) DisplayError(_("Position not found in file"), 0); return FALSE; } - // [HGM] FEN can begin with digit, any piece letter valid in this variant, or a + for Shogi promoted pieces - fenMode = line[0] >= '0' && line[0] <= '9' || line[0] == '+' || CharToPiece(line[0]) != EmptySquare; + // [HGM] FEN can begin with digit, any piece letter valid in this variant, or a + for Shogi promoted pieces (or * for blackout) + fenMode = line[0] >= '0' && line[0] <= '9' || line[0] == '+' || line[0] == '*' || CharToPiece(line[0]) != EmptySquare; if (pn >= 2) { if (fenMode || line[0] == '#') pn--; @@ -17836,6 +17878,7 @@ PositionToFEN (int move, char *overrideCastling, int moveCounts) piece = (ChessSquare)(CHUDEMOTED piece); } *p++ = (piece == DarkSquare ? '*' : PieceToChar(piece)); + if(*p = PieceSuffix(piece)) p++; if(p[-1] == '~') { /* [HGM] flag promoted pieces as '~' (Crazyhouse) */ p[-1] = PieceToChar((ChessSquare)(CHUDEMOTED piece)); @@ -18055,13 +18098,20 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen, Boolean autoSize) if (i != 0 && i != BOARD_HEIGHT-1) return FALSE; // only on back-rank board[i][(j++)+gameInfo.holdingsWidth] = ClearBoard; p++; subst++; // placeHolder } else if (*p == '+' || isalpha(*p)) { + char *q, *s = SUFFIXES; if (j >= gameInfo.boardWidth) return FALSE; if(*p=='+') { - piece = CharToPiece(*++p); + char c = *++p; + if(q = strchr(s, p[1])) p++; + piece = CharToPiece(c + (q ? 64*(q - s + 1) : 0)); if(piece == EmptySquare) return FALSE; /* unknown piece */ piece = (ChessSquare) (CHUPROMOTED piece ); p++; if(PieceToChar(piece) != '+') return FALSE; /* unpromotable piece */ - } else piece = CharToPiece(*p++); + } else { + char c = *p++; + if(q = strchr(s, *p)) p++; + piece = CharToPiece(c + (q ? 64*(q - s + 1) : 0)); + } if(piece==EmptySquare) return FALSE; /* unknown piece */ if(*p == '~') { /* [HGM] make it a promoted piece for Crazyhouse */