X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=26ebe3cc49562e90042c511f8638f1ad0320c812;hb=f29ff21f23c2a22fc55e14ba48c53d704c22289d;hp=b313fa5ad100e04f3a64c5edffb841dbfe94654d;hpb=98a0bc48e8cc10b05bd9eea57bfc204b62e9aeb6;p=xboard.git diff --git a/backend.c b/backend.c index b313fa5..26ebe3c 100644 --- a/backend.c +++ b/backend.c @@ -234,7 +234,7 @@ void InitDrawingSizes(int x, int y); void NextMatchGame P((void)); int NextTourneyGame P((int nr, int *swap)); int Pairing P((int nr, int nPlayers, int *w, int *b, int *sync)); -FILE *WriteTourneyFile P((char *results)); +FILE *WriteTourneyFile P((char *results, FILE *f)); void DisplayTwoMachinesTitle P(()); #ifdef WIN32 @@ -981,6 +981,7 @@ InitBackEnd1() GetTimeMark(&programStartTime); srandom((programStartTime.ms + 1000*programStartTime.sec)*0x1001001); // [HGM] book: makes sure random is unpredictabe to msec level + appData.seedBase = random() + (random()<<15); pauseStart = programStartTime; pauseStart.sec -= 100; // [HGM] matchpause: fake a pause that has long since ended ClearProgramStats(); @@ -1436,7 +1437,7 @@ MatchEvent(int mode) if(strchr(appData.results, '*') == NULL) { FILE *f; appData.tourneyCycles++; - if(f = WriteTourneyFile(appData.results)) { // make a tourney file with increased number of cycles + if(f = WriteTourneyFile(appData.results, NULL)) { // make a tourney file with increased number of cycles fclose(f); NextTourneyGame(-1, &dummy); ReserveGame(-1, 0); @@ -9720,12 +9721,13 @@ CountPlayers(char *p) } FILE * -WriteTourneyFile(char *results) +WriteTourneyFile(char *results, FILE *f) { // write tournament parameters on tourneyFile; on success return the stream pointer for closing - FILE *f = fopen(appData.tourneyFile, "w"); + if(f == NULL) f = fopen(appData.tourneyFile, "w"); if(f == NULL) DisplayError(_("Could not write on tourney file"), 0); else { // create a file with tournament description fprintf(f, "-participants {%s}\n", appData.participants); + fprintf(f, "-seedBase %d\n", appData.seedBase); fprintf(f, "-tourneyType %d\n", appData.tourneyType); fprintf(f, "-tourneyCycles %d\n", appData.tourneyCycles); fprintf(f, "-defaultMatchGames %d\n", appData.defaultMatchGames); @@ -9749,10 +9751,73 @@ WriteTourneyFile(char *results) return f; } +#define MAXENGINES 1000 +char *command[MAXENGINES], *mnemonic[MAXENGINES]; + +void Substitute(char *participants, int expunge) +{ + int i, changed, changes=0, nPlayers=0; + char *p, *q, *r, buf[MSG_SIZ]; + if(participants == NULL) return; + if(appData.tourneyFile[0] == NULLCHAR) { free(participants); return; } + r = p = participants; q = appData.participants; + while(*p && *p == *q) { + if(*p == '\n') r = p+1, nPlayers++; + p++; q++; + } + if(*p) { // difference + while(*p && *p++ != '\n'); + while(*q && *q++ != '\n'); + changed = nPlayers; + changes = 1 + (strcmp(p, q) != 0); + } + if(changes == 1) { // a single engine mnemonic was changed + q = r; while(*q) nPlayers += (*q++ == '\n'); + p = buf; while(*r && (*p = *r++) != '\n') p++; + *p = NULLCHAR; + NamesToList(firstChessProgramNames, command, mnemonic); + for(i=1; mnemonic[i]; i++) if(!strcmp(buf, mnemonic[i])) break; + if(mnemonic[i]) { // The substitute is valid + FILE *f; + if(appData.tourneyFile[0] && (f = fopen(appData.tourneyFile, "r+")) ) { + flock(fileno(f), LOCK_EX); + ParseArgsFromFile(f); + fseek(f, 0, SEEK_SET); + FREE(appData.participants); appData.participants = participants; + if(expunge) { // erase results of replaced engine + int len = strlen(appData.results), w, b, dummy; + for(i=0; i 1) DisplayError(_("You can only change one engine at the time"), 0); + free(participants); + return; +} + int CreateTourney(char *name) { FILE *f; + if(matchMode && strcmp(name, appData.tourneyFile)) { + ASSIGN(name, appData.tourneyFile); //do not allow change of tourneyfile while playing + } if(name[0] == NULLCHAR) { if(appData.participants[0]) DisplayError(_("You must supply a tournament file,\nfor storing the tourney progress"), 0); @@ -9770,7 +9835,7 @@ CreateTourney(char *name) } ASSIGN(appData.tourneyFile, name); if(appData.tourneyType < 0) appData.defaultMatchGames = 1; // Swiss forces games/pairing = 1 - if((f = WriteTourneyFile("")) == NULL) return 0; + if((f = WriteTourneyFile("", NULL)) == NULL) return 0; } fclose(f); appData.noChessProgram = FALSE; @@ -9779,9 +9844,6 @@ CreateTourney(char *name) return 1; } -#define MAXENGINES 1000 -char *command[MAXENGINES], *mnemonic[MAXENGINES]; - void NamesToList(char *names, char **engineList, char **engineMnemonic) { char buf[MSG_SIZ], *p, *q; @@ -9804,7 +9866,7 @@ void NamesToList(char *names, char **engineList, char **engineMnemonic) names = p; i++; if(i > MAXENGINES - 2) break; } - engineList[i] = NULL; + engineList[i] = engineMnemonic[i] = NULL; } // following implemented as macro to avoid type limitations @@ -9966,6 +10028,7 @@ NextMatchGame() first.twoMachinesColor = firstWhite ? "white\n" : "black\n"; // perform actual color assignement second.twoMachinesColor = firstWhite ? "black\n" : "white\n"; appData.noChessProgram = (first.pr == NoProc); // kludge to prevent Reset from starting up chess program + if(appData.loadGameIndex == -2) srandom(appData.seedBase + 68163*(nextGame & ~1)); // deterministic seed to force same opening Reset(FALSE, first.pr != NoProc); appData.noChessProgram = FALSE; if(!LoadGameOrPosition(matchGame)) return; // setup game; abort when bad game/pos file @@ -11081,7 +11144,7 @@ int GameContainsPosition(FILE *f, ListGame *lg) static int initDone=FALSE; if(!initDone) { - for(next = WhitePawn; next>8 ^ rand()<<6 ^rand()<<20; + for(next = WhitePawn; next>8 ^ random()<<6 ^random()<<20; initDone = TRUE; } dummyInfo.variant = VariantNormal;