X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=93f79d37335d0f2314a0c286cd789f3ad34d66a5;hb=3845dc6e578a5e2ca1df4ed90a5db36f7529ac30;hp=a5207923aa2a6569c7d6bef8a605c7b38694ebe9;hpb=13fa8dd75ddaa317141502a09766a78ecfe218e6;p=xboard.git diff --git a/backend.c b/backend.c index a520792..93f79d3 100644 --- a/backend.c +++ b/backend.c @@ -418,7 +418,7 @@ char cmailMove[CMAIL_MAX_GAMES][MOVE_LEN], cmailMsg[MSG_SIZ]; char bookOutput[MSG_SIZ*10], thinkOutput[MSG_SIZ*10], lastHint[MSG_SIZ]; char thinkOutput1[MSG_SIZ*10]; -ChessProgramState first, second; +ChessProgramState first, second, pairing; /* premove variables */ int premoveToX = 0; @@ -1019,6 +1019,13 @@ InitBackEnd1() InitEngine(&second, 1); CommonEngineInit(); + pairing.which = "pairing"; // pairing engine + pairing.pr = NoProc; + pairing.isr = NULL; + pairing.program = appData.pairingEngine; + pairing.host = "localhost"; + pairing.dir = "."; + if (appData.icsActive) { appData.clockMode = TRUE; /* changes dynamically in ICS mode */ } else if (appData.noChessProgram) { // [HGM] st: searchTime mode now also is clockMode @@ -1403,10 +1410,10 @@ MatchEvent(int mode) // return; // } abortMatch = FALSE; - appData.matchGames = appData.defaultMatchGames; + if(mode == 2) appData.matchGames = appData.defaultMatchGames; /* Set up machine vs. machine match */ nextGame = 0; - NextTourneyGame(0, &dummy); // sets appData.matchGames if this is tourney, to make sure ReserveGame knows it + NextTourneyGame(-1, &dummy); // sets appData.matchGames if this is tourney, to make sure ReserveGame knows it if(appData.tourneyFile[0]) { ReserveGame(-1, 0); if(nextGame > appData.matchGames) { @@ -7132,6 +7139,8 @@ TourneyStandings(int display) int score[MAXPLAYERS], ranking[MAXPLAYERS], points[MAXPLAYERS], games[MAXPLAYERS]; char result, *p, *names[MAXPLAYERS]; + if(appData.tourneyType < 0) return strdup("Swiss tourney finished"); // standings of Swiss yet TODO + names[0] = p = strdup(appData.participants); while(p = strchr(p, '\n')) *p++ = NULLCHAR, names[++nPlayers] = p; // count participants @@ -7630,6 +7639,8 @@ void DeferredBookMove(void) HandleMachineMove(savedMessage, savedState); } +static int savedWhitePlayer, savedBlackPlayer, pairingReceived; + void HandleMachineMove(message, cps) char *message; @@ -7644,6 +7655,14 @@ HandleMachineMove(message, cps) int machineWhite; char *bookHit; + if(cps == &pairing && sscanf(message, "%d-%d", &savedWhitePlayer, &savedBlackPlayer) == 2) { + // [HGM] pairing: Mega-hack! Pairing engine also uses this routine (so it could give other WB commands). + if(savedWhitePlayer == 0 || savedBlackPlayer == 0) return; + pairingReceived = 1; + NextMatchGame(); + return; // Skim the pairing messages here. + } + cps->userError = 0; FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book hit @@ -9534,6 +9553,35 @@ TwoMachinesEventIfReady P((void)) TwoMachinesEvent(); } +char * +MakeName(char *template) +{ + time_t clock; + struct tm *tm; + static char buf[MSG_SIZ]; + char *p = buf; + int i; + + clock = time((time_t *)NULL); + tm = localtime(&clock); + + while(*p++ = *template++) if(p[-1] == '%') { + switch(*template++) { + case 0: *p = 0; return buf; + case 'Y': i = tm->tm_year+1900; break; + case 'y': i = tm->tm_year-100; break; + case 'M': i = tm->tm_mon+1; break; + case 'd': i = tm->tm_mday; break; + case 'h': i = tm->tm_hour; break; + case 'm': i = tm->tm_min; break; + case 's': i = tm->tm_sec; break; + default: i = 0; + } + snprintf(p-1, MSG_SIZ-10 - (p - buf), "%02d", i); p += strlen(p); + } + return buf; +} + int CountPlayers(char *p) { @@ -9577,17 +9625,21 @@ CreateTourney(char *name) { FILE *f; if(name[0] == NULLCHAR) { - DisplayError(_("You must supply a tournament file,\nfor storing the tourney progress"), 0); + if(appData.participants[0]) + DisplayError(_("You must supply a tournament file,\nfor storing the tourney progress"), 0); return 0; } - f = fopen(appData.tourneyFile, "r"); + f = fopen(name, "r"); if(f) { // file exists + ASSIGN(appData.tourneyFile, name); ParseArgsFromFile(f); // parse it } else { - if(CountPlayers(appData.participants) < appData.tourneyType + (!appData.tourneyType) + 1) { + if(!appData.participants[0]) return 0; // ignore tourney file if non-existing & no participants + if(CountPlayers(appData.participants) < (appData.tourneyType>0 ? appData.tourneyType+1 : 2)) { DisplayError(_("Not enough participants"), 0); return 0; } + ASSIGN(appData.tourneyFile, name); if((f = WriteTourneyFile("")) == NULL) return 0; } fclose(f); @@ -9664,7 +9716,7 @@ SetPlayer(int player) int Pairing(int nr, int nPlayers, int *whitePlayer, int *blackPlayer, int *syncInterval) { // determine players from game number - int curCycle, curRound, curPairing, gamesPerCycle, gamesPerRound, roundsPerCycle, pairingsPerRound; + int curCycle, curRound, curPairing, gamesPerCycle, gamesPerRound, roundsPerCycle=1, pairingsPerRound=1; if(appData.tourneyType == 0) { roundsPerCycle = (nPlayers - 1) | 1; @@ -9711,7 +9763,7 @@ int NextTourneyGame(int nr, int *swapColors) { // !!!major kludge!!! fiddle appData settings to get everything in order for next tourney game char *p, *q; - int whitePlayer, blackPlayer, firstBusy=1000000000, syncInterval = 0, nPlayers=0; + int whitePlayer, blackPlayer, firstBusy=1000000000, syncInterval = 0, nPlayers; FILE *tf; if(appData.tourneyFile[0] == NULLCHAR) return 1; // no tourney, always allow next game tf = fopen(appData.tourneyFile, "r"); @@ -9719,9 +9771,24 @@ NextTourneyGame(int nr, int *swapColors) ParseArgsFromFile(tf); fclose(tf); InitTimeControls(); // TC might be altered from tourney file - p = appData.participants; - while(p = strchr(p, '\n')) p++, nPlayers++; // count participants - *swapColors = Pairing(nr, nPlayers, &whitePlayer, &blackPlayer, &syncInterval); + nPlayers = CountPlayers(appData.participants); // count participants + if(appData.tourneyType < 0 && appData.pairingEngine[0]) { + if(nr>=0 && !pairingReceived) { + char buf[1<<16]; + if(pairing.pr == NoProc) StartChessProgram(&pairing); + snprintf(buf, 1<<16, "results %d %s\n", nPlayers, appData.results); + SendToProgram(buf, &pairing); + snprintf(buf, 1<<16, "pairing %d\n", nr+1); + SendToProgram(buf, &pairing); + return 0; // wait for pairing engine to answer (which causes NextTourneyGame to be called again... + } + pairingReceived = 0; // ... so we continue here + syncInterval = nPlayers/2; *swapColors = 0; + appData.matchGames = appData.tourneyCycles * syncInterval - 1; + whitePlayer = savedWhitePlayer-1; blackPlayer = savedBlackPlayer-1; + matchGame = 1; roundNr = nr / syncInterval + 1; + } else + *swapColors = Pairing(nr<0 ? 0 : nr, nPlayers, &whitePlayer, &blackPlayer, &syncInterval); if(syncInterval) { p = q = appData.results; @@ -12310,6 +12377,9 @@ ExitEvent(status) RemoveInputSource(second.isr); } + if (pairing.pr != NoProc) SendToProgram("quit\n", &pairing); + if (pairing.isr != NULL) RemoveInputSource(pairing.isr); + ShutDownFrontEnd(); exit(status); } @@ -12621,6 +12691,12 @@ DisplayTwoMachinesTitle() { char buf[MSG_SIZ]; if (appData.matchGames > 0) { + if(appData.tourneyFile[0]) { + snprintf(buf, MSG_SIZ, "%s vs. %s (%d/%d%s)", + gameInfo.white, gameInfo.black, + nextGame+1, appData.matchGames+1, + appData.tourneyType>0 ? "gt" : appData.tourneyType<0 ? "sw" : "rr"); + } else if (first.twoMachinesColor[0] == 'w') { snprintf(buf, MSG_SIZ, "%s vs. %s (%d-%d-%d)", gameInfo.white, gameInfo.black,