X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=2f839b98cc6ddcbbdae843a0d05c63b6bdd62b4b;hb=00f6fcd2f683cda76e458177526a96f94957d345;hp=674b14a05b6db07cf313682e5f18ef8d1a447d1c;hpb=08c9436657f0649356c3b16d8cb8cafb0a3b8c31;p=xboard.git diff --git a/backend.c b/backend.c index 674b14a..2f839b9 100644 --- a/backend.c +++ b/backend.c @@ -151,7 +151,6 @@ void SendToICS P((char *s)); void SendToICSDelayed P((char *s, long msdelay)); void SendMoveToICS P((ChessMove moveType, int fromX, int fromY, int toX, int toY)); -void InitPosition P((int redraw)); void HandleMachineMove P((char *message, ChessProgramState *cps)); int AutoPlayOneMove P((void)); int LoadGameOneMove P((ChessMove readAhead)); @@ -242,6 +241,7 @@ int whiteNPS, blackNPS; /* [HGM] nps: for easily making clocks aware of NPS VariantClass currentlyInitializedVariant; /* [HGM] variantswitch */ int lastIndex = 0; /* [HGM] autoinc: last game/position used in match mode */ int opponentKibitzes; +int lastSavedGame; /* [HGM] save: ID of game */ /* States for ics_getting_history */ #define H_FALSE 0 @@ -456,10 +456,10 @@ AppData appData; Board boards[MAX_MOVES]; /* [HGM] Following 7 needed for accurate legality tests: */ -char epStatus[MAX_MOVES]; -char castlingRights[MAX_MOVES][BOARD_SIZE]; // stores files for pieces with castling rights or -1 -char castlingRank[BOARD_SIZE]; // and corresponding ranks -char initialRights[BOARD_SIZE], FENcastlingRights[BOARD_SIZE], fileRights[BOARD_SIZE]; +signed char epStatus[MAX_MOVES]; +signed char castlingRights[MAX_MOVES][BOARD_SIZE]; // stores files for pieces with castling rights or -1 +signed char castlingRank[BOARD_SIZE]; // and corresponding ranks +signed char initialRights[BOARD_SIZE], FENcastlingRights[BOARD_SIZE], fileRights[BOARD_SIZE]; int nrCastlingRights; // For TwoKings, or to implement castling-unknown status int initialRulePlies, FENrulePlies; char FENepStatus; @@ -2109,9 +2109,10 @@ read_from_ics(isr, closure, data, count, error) if (data[i] != NULLCHAR && data[i] != '\r') buf[buf_len++] = data[i]; if(buf_len >= 5 && buf[buf_len-5]=='\n' && buf[buf_len-4]=='\\' && - buf[buf_len-3]==' ' && buf[buf_len-2]==' ' && buf[buf_len-1]==' ') + buf[buf_len-3]==' ' && buf[buf_len-2]==' ' && buf[buf_len-1]==' ') { buf_len -= 5; // [HGM] ICS: join continuation line of Lasker 2.2.3 server with previous buf[buf_len++] = ' '; // replace by space (assumes ICS does not break lines within word) + } } buf[buf_len] = NULLCHAR; @@ -2415,14 +2416,15 @@ read_from_ics(isr, closure, data, count, error) #endif #endif } // [DM] 'else { ' deleted - if (/* Don't color "message" or "messages" output */ - (tkind = 5, looking_at(buf, &i, "*. * (*:*): ")) || - looking_at(buf, &i, "*. * at *:*: ") || - looking_at(buf, &i, "--* (*:*): ") || + if ( /* Regular tells and says */ (tkind = 1, looking_at(buf, &i, "* tells you: ")) || looking_at(buf, &i, "* (your partner) tells you: ") || looking_at(buf, &i, "* says: ") || + /* Don't color "message" or "messages" output */ + (tkind = 5, looking_at(buf, &i, "*. * (*:*): ")) || + looking_at(buf, &i, "*. * at *:*: ") || + looking_at(buf, &i, "--* (*:*): ") || /* Message notifications (same color as tells) */ looking_at(buf, &i, "* has left a message ") || looking_at(buf, &i, "* just sent you a message:\n") || @@ -7718,6 +7720,28 @@ void UserAdjudicationEvent( int result ) } +// [HGM] save: calculate checksum of game to make games easily identifiable +int StringCheckSum(char *s) +{ + int i = 0; + if(s==NULL) return 0; + while(*s) i = i*259 + *s++; + return i; +} + +int GameCheckSum() +{ + int i, sum=0; + for(i=backwardMostMove; i1 && sum==0) sum++; // make sure never zero for non-empty game + return sum + StringCheckSum(commentList[i]); +} // end of save patch + void GameEnds(result, resultDetails, whosays) ChessMove result; @@ -7867,7 +7891,9 @@ GameEnds(result, resultDetails, whosays) DisplayMove(currentMove - 1); if (forwardMostMove != 0) { - if (gameMode != PlayFromGameFile && gameMode != EditGame) { + if (gameMode != PlayFromGameFile && gameMode != EditGame + && lastSavedGame != GameCheckSum() // [HGM] save: suppress duplicates + ) { if (*appData.saveGameFile != NULLCHAR) { SaveGameToFile(appData.saveGameFile, TRUE); } else if (appData.autoSaveGames) { @@ -8211,6 +8237,7 @@ Reset(redraw, init) DisplayTitle(""); DisplayMessage("", ""); HistorySet(parseList, backwardMostMove, forwardMostMove, currentMove-1); + lastSavedGame = 0; // [HGM] save: make sure next game counts as unsaved } void @@ -9701,6 +9728,7 @@ SaveGamePGN(f) } fclose(f); + lastSavedGame = GameCheckSum(); // [HGM] save: remember ID of last saved game to prevent double saving return TRUE; } @@ -9777,6 +9805,7 @@ SaveGame(f, dummy, dummy2) char *dummy2; { if (gameMode == EditPosition) EditPositionDone(); + lastSavedGame = GameCheckSum(); // [HGM] save: remember ID of last saved game to prevent double saving if (appData.oldSaveStyle) return SaveGameOldStyle(f); else @@ -10883,8 +10912,19 @@ ExitAnalyzeMode() void EditPositionDone() { + int king = gameInfo.variant == VariantKnightmate ? WhiteUnicorn : WhiteKing; + startedFromSetupPosition = TRUE; InitChessProgram(&first, FALSE); + castlingRights[0][2] = castlingRights[0][5] = BOARD_WIDTH>>1; + if(boards[0][0][BOARD_WIDTH>>1] == king) { + castlingRights[0][1] = boards[0][0][BOARD_LEFT] == WhiteRook ? 0 : -1; + castlingRights[0][0] = boards[0][0][BOARD_RGHT-1] == WhiteRook ? BOARD_RGHT-1 : -1; + } else castlingRights[0][2] = -1; + if(boards[0][BOARD_HEIGHT-1][BOARD_WIDTH>>1] == WHITE_TO_BLACK king) { + castlingRights[0][4] = boards[0][BOARD_HEIGHT-1][BOARD_LEFT] == BlackRook ? 0 : -1; + castlingRights[0][3] = boards[0][BOARD_HEIGHT-1][BOARD_RGHT-1] == BlackRook ? BOARD_RGHT-1 : -1; + } else castlingRights[0][5] = -1; SendToProgram("force\n", &first); if (blackPlaysFirst) { strcpy(moveList[0], ""); @@ -12520,7 +12560,11 @@ ParseFeatures(args, cps) if (BoolFeature(&p, "smp", &cps->maxCores, cps)) continue; if (StringFeature(&p, "egt", &cps->egtFormats, cps)) continue; if (StringFeature(&p, "option", &(cps->option[cps->nrOptions].name), cps)) { - ParseOption(&(cps->option[cps->nrOptions++]), cps); // [HGM] options: add option feature + if(!ParseOption(&(cps->option[cps->nrOptions++]), cps)) { // [HGM] options: add option feature + sprintf(buf, "rejected option %s\n", cps->option[--cps->nrOptions].name); + SendToProgram(buf, cps); + continue; + } if(cps->nrOptions >= MAX_OPTIONS) { cps->nrOptions--; sprintf(buf, "%s engine has too many options\n", cps->which);