X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=c18fa3eb6ea146641af06f9fa9bca4745d9079a4;hb=28a742f1ef86e353f4eed6ec0841d483b29a5794;hp=5c37e3efccac380dd8212b01c93d7b5806432a92;hpb=94a0acbcf696ce1aee4fb48537819c6c24d16c88;p=xboard.git diff --git a/backend.c b/backend.c index 5c37e3e..c18fa3e 100644 --- a/backend.c +++ b/backend.c @@ -1600,6 +1600,7 @@ InitBackEnd3 P((void)) char buf[MSG_SIZ]; int err, len; + ParseFeatures(appData.features[0], &first); if(!appData.icsActive && !appData.noChessProgram && !appData.matchMode && // mode involves only first engine !strcmp(appData.variant, "normal") && // no explicit variant request appData.NrRanks == -1 && appData.NrFiles == -1 && appData.holdingsSize == -1 && // no size overrides requested @@ -4301,7 +4302,7 @@ read_from_ics (InputSourceRef isr, VOIDSTAR closure, char *data, int count, int } else if (count == 0) { RemoveInputSource(isr); - DisplayFatalError(_("Connection closed by ICS"), 0, 0); + DisplayFatalError(_("Connection closed by ICS"), 0, 6666); } else { DisplayFatalError(_("Error reading from ICS"), error, 1); } @@ -10212,16 +10213,16 @@ ParseGameHistory (char *game) void ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) { - ChessSquare captured = board[toY][toX], piece, pawn, king, killed, killed2; int p, rookX, oldEP, epRank, berolina = 0; + ChessSquare captured = board[toY][toX], piece, pawn, king, killed, killed2; int p, rookX, oldEP, epRank, epFile, lastFile, lastRank, berolina = 0; int promoRank = gameInfo.variant == VariantMakruk || gameInfo.variant == VariantGrand || gameInfo.variant == VariantChuChess ? 3 : 1; /* [HGM] compute & store e.p. status and castling rights for new position */ /* we can always do that 'in place', now pointers to these rights are passed to ApplyMove */ if(gameInfo.variant == VariantBerolina) berolina = EP_BEROLIN_A; - oldEP = (signed char)board[EP_FILE]; epRank = board[EP_RANK]; + oldEP = (signed char)board[EP_STATUS]; epRank = board[EP_RANK]; epFile = board[EP_FILE]; lastFile = board[LAST_FILE],lastRank = board[LAST_RANK]; board[EP_STATUS] = EP_NONE; - board[EP_FILE] = board[EP_RANK] = 100; + board[EP_FILE] = board[EP_RANK] = board[LAST_FILE] = board[LAST_RANK] = 100; if (fromY == DROP_RANK) { /* must be first */ @@ -10253,6 +10254,13 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) } pawn = board[fromY][fromX]; + if(pieceDesc[pawn] && strchr(pieceDesc[pawn], 'e')) { // piece with user-defined e.p. capture + if(captured == EmptySquare && toX == epFile && (toY == (epRank & 127) || toY + (pawn < BlackPawn ? -1 : 1) == epRank - 128)) { + captured = board[lastRank][lastFile]; // remove victim + board[lastRank][lastFile] = EmptySquare; + pawn = EmptySquare; // kludge to suppress old e.p. code + } + } if( pawn == WhiteLance || pawn == BlackLance ) { if( gameInfo.variant != VariantSuper && gameInfo.variant != VariantChu ) { if(gameInfo.variant == VariantSpartan) board[EP_STATUS] = EP_PAWN_MOVE; // in Spartan no e.p. rights must be set @@ -10270,6 +10278,7 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) if(toX fromX) board[EP_STATUS] = toX; + board[LAST_FILE] = toX; board[LAST_RANK] = toY; } } else if( pawn == BlackPawn ) { @@ -10283,6 +10292,7 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) if(toX fromX) board[EP_STATUS] = toX; + board[LAST_FILE] = toX; board[LAST_RANK] = toY; } } @@ -10377,18 +10387,16 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) board[toY][toX] = (ChessSquare) (PROMOTED(board[toY][toX])); board[fromY][fromX] = EmptySquare; } else if ((fromY >= BOARD_HEIGHT>>1) - && (oldEP == toX || oldEP == EP_UNKNOWN || appData.testLegality || abs(toX - fromX) > 4) + && (epFile == toX || oldEP == EP_UNKNOWN || appData.testLegality || abs(toX - fromX) > 4) && (toX != fromX) && gameInfo.variant != VariantXiangqi && gameInfo.variant != VariantBerolina && (pawn == WhitePawn) && (board[toY][toX] == EmptySquare)) { + if(lastFile == 100) lastFile = (board[fromY][toX] == BlackPawn ? toX : fromX), lastRank = fromY; // assume FIDE e.p. if victim present board[fromY][fromX] = EmptySquare; board[toY][toX] = piece; - if(toY == epRank - 128 + 1) - captured = board[toY - 2][toX], board[toY - 2][toX] = EmptySquare; - else - captured = board[toY - 1][toX], board[toY - 1][toX] = EmptySquare; + captured = board[lastRank][lastFile], board[lastRank][lastFile] = EmptySquare; } else if ((fromY == BOARD_HEIGHT-4) && (toX == fromX) && gameInfo.variant == VariantBerolina @@ -10444,18 +10452,16 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) board[toY][toX] = (ChessSquare) (PROMOTED(board[toY][toX])); board[fromY][fromX] = EmptySquare; } else if ((fromY < BOARD_HEIGHT>>1) - && (oldEP == toX || oldEP == EP_UNKNOWN || appData.testLegality || abs(toX - fromX) > 4) + && (epFile == toX && epRank == toY || oldEP == EP_UNKNOWN || appData.testLegality || abs(toX - fromX) > 4) && (toX != fromX) && gameInfo.variant != VariantXiangqi && gameInfo.variant != VariantBerolina && (pawn == BlackPawn) && (board[toY][toX] == EmptySquare)) { + if(lastFile == 100) lastFile = (board[fromY][toX] == WhitePawn ? toX : fromX), lastRank = fromY; board[fromY][fromX] = EmptySquare; board[toY][toX] = piece; - if(toY == epRank - 128 - 1) - captured = board[toY + 2][toX], board[toY + 2][toX] = EmptySquare; - else - captured = board[toY + 1][toX], board[toY + 1][toX] = EmptySquare; + captured = board[lastRank][lastFile], board[lastRank][lastFile] = EmptySquare; } else if ((fromY == 3) && (toX == fromX) && gameInfo.variant == VariantBerolina @@ -14877,7 +14883,9 @@ MachineWhiteEvent () safeStrCpy(bookMove, "move ", sizeof(bookMove)/sizeof(bookMove[0])); strcat(bookMove, bookHit); - HandleMachineMove(bookMove, &first); + savedMessage = bookMove; // args for deferred call + savedState = &first; + ScheduleDelayedEvent(DeferredBookMove, 1); } } @@ -14952,7 +14960,9 @@ MachineBlackEvent () safeStrCpy(bookMove, "move ", sizeof(bookMove)/sizeof(bookMove[0])); strcat(bookMove, bookHit); - HandleMachineMove(bookMove, &first); + savedMessage = bookMove; // args for deferred call + savedState = &first; + ScheduleDelayedEvent(DeferredBookMove, 1); } } @@ -15022,7 +15032,7 @@ WaitForEngine (ChessProgramState *cps, DelayedEventCallback retry) void TwoMachinesEvent P((void)) { - int i; + int i, move = forwardMostMove; char buf[MSG_SIZ]; ChessProgramState *onmove; char *bookHit = NULL; @@ -15139,8 +15149,8 @@ TwoMachinesEvent P((void)) } } - ResetClocks(); - if (!first.sendTime || !second.sendTime) { + if (!first.sendTime || !second.sendTime || move == 0) { // [HGM] first engine changed sides from Reset, so recalc time odds + ResetClocks(); timeRemaining[0][forwardMostMove] = whiteTimeRemaining; timeRemaining[1][forwardMostMove] = blackTimeRemaining; } @@ -17166,8 +17176,10 @@ StringFeature (char **p, char *name, char **loc, ChessProgramState *cps) if (strncmp((*p), name, len) == 0 && (*p)[len] == '=' && (*p)[len+1] == '\"') { (*p) += len + 2; - ASSIGN(*loc, *p); // kludge alert: assign rest of line just to be sure allocation is large enough so that sscanf below always fits - sscanf(*p, "%[^\"]", *loc); + len = strlen(*p) + 1; if(len < MSG_SIZ && !strcmp(name, "option")) len = MSG_SIZ; // make sure string options have enough space to change their value + FREE(*loc); *loc = malloc(len); + strncpy(*loc, *p, len); + sscanf(*p, "%[^\"]", *loc); // should always fit, because we allocated at least strlen(*p) while (**p && **p != '\"') (*p)++; if (**p == '\"') (*p)++; snprintf(buf, MSG_SIZ, "accepted %s\n", name);