A new option -seedBase is added, and written to the tourney file.
It allows all XBoard instances working on a tourney to generate the same
'random' openings in a deterministic way, based on this one-time seed
and the game number. When -loadGameIndex equals -2, it uses the same seed
for an odd and the following even game.
{ "results", ArgString, (void *) &appData.results, FALSE, (ArgIniType) "" },
{ "syncAfterRound", ArgBoolean, (void *) &appData.roundSync, FALSE, (ArgIniType) FALSE },
{ "syncAfterCycle", ArgBoolean, (void *) &appData.cycleSync, FALSE, (ArgIniType) TRUE },
+ { "seedBase", ArgInt, (void *) &appData.seedBase, FALSE, (ArgIniType) 1 },
/* [HGM] board-size, adjudication and misc. options */
{ "oneClickMove", ArgBoolean, (void *) &appData.oneClick, TRUE, (ArgIniType) FALSE },
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();
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);
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
char *participants;
int tourneyType;
int tourneyCycles;
+ int seedBase;
Boolean roundSync;
Boolean cycleSync;
} AppData, *AppDataPtr;
int MatchOK()\r
{\r
if(autoinc) appData.loadGameIndex = appData.loadPositionIndex = -(twice + 1);\r
+ if(!appData.loadGameFile[0]) appData.loadGameIndex = -2*twice; // kludge to pass value of "twice" for use in GUI book\r
if(swiss) { appData.defaultMatchGames = 1; appData.tourneyType = -1; }\r
if(CreateTourney(tfName) && !matchMode) { // CreateTourney reloads original settings if file already existed\r
MatchEvent(2);\r
NamesToList(firstChessProgramNames, engineList, engineMnemonic);\r
comboCallback = &AddToTourney;\r
autoinc = appData.loadGameIndex < 0 || appData.loadPositionIndex < 0;\r
- twice = TRUE; swiss = appData.tourneyType < 0;\r
+ twice = FALSE; swiss = appData.tourneyType < 0;\r
while(engineList[n]) n++; tourneyOptions[3].max = n-1;\r
snprintf(title, MSG_SIZ, _("Tournament and Match Options"));\r
ASSIGN(tfName, appData.tourneyFile[0] ? appData.tourneyFile : MakeName(appData.defName));\r