X-Git-Url: http://winboard.nl/cgi-bin?p=xboard.git;a=blobdiff_plain;f=zippy.c;h=247240dbf69b525b66635094853601874ee1a895;hp=564140e1251a22affbc5e4fac19920b253f3c335;hb=5cab485d7a39f1b15558fc3b06d57d2164a7dc5d;hpb=5d495e94dd1f3f2a334e11b45719d765e4c32c3c diff --git a/zippy.c b/zippy.c index 564140e..247240d 100644 --- a/zippy.c +++ b/zippy.c @@ -1,9 +1,13 @@ /* * zippy.c -- Implements Zippy the Pinhead chess player on ICS in XBoard - * $Id$ * - * Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts. - * Enhancements Copyright 1992-2001 Free Software Foundation, Inc. + * Copyright 1991 by Digital Equipment Corporation, Maynard, + * Massachusetts. + * + * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, + * 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Free Software Foundation, Inc. + * + * Enhancements Copyright 2005 Alessandro Scotti * * The following terms apply to Digital Equipment Corporation's copyright * interest in XBoard: @@ -27,24 +31,25 @@ * SOFTWARE. * ------------------------------------------------------------------------ * - * The following terms apply to the enhanced version of XBoard distributed - * by the Free Software Foundation: + * The following terms apply to the enhanced version of XBoard + * distributed by the Free Software Foundation: * ------------------------------------------------------------------------ - * This program is free software; you can redistribute it and/or modify + * + * GNU XBoard is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU XBoard is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * ------------------------------------------------------------------------ - */ + * along with this program. If not, see http://www.gnu.org/licenses/. + * + *------------------------------------------------------------------------ + ** See the file ChangeLog for a revision history. */ #include "config.h" @@ -88,15 +93,20 @@ extern char *getenv(); #include "backend.h" #include "backendz.h" +char *SendMoveToBookUser P((int nr, ChessProgramState *cps, int initial)); // [HGM] book +void HandleMachineMove P((char *message, ChessProgramState *cps)); + static char zippyPartner[MSG_SIZ]; static char zippyLastOpp[MSG_SIZ]; +static char zippyOffender[MSG_SIZ]; // [HGM] aborter static int zippyConsecGames; static time_t zippyLastGameEnd; extern void mysrandom(unsigned int seed); extern int myrandom(void); -void ZippyInit() +void +ZippyInit () { char *p; @@ -190,7 +200,7 @@ void ZippyInit() if (p != NULL) { appData.zippyVariants = p; } - strcpy(first.variants, appData.zippyVariants); + ASSIGN(first.variants, appData.zippyVariants); srandom(time(NULL)); } @@ -295,8 +305,8 @@ char *swifties[] = { #define MAX_SPEECH 250 -void Speak(how, whom) - char *how, *whom; +void +Speak (char *how, char *whom) { static FILE *zipfile = NULL; static struct stat zipstat; @@ -305,7 +315,6 @@ void Speak(how, whom) time_t now; char *p; int c, speechlen; - Boolean done; if (strcmp(how, "shout") == 0) { now = time((time_t *) NULL); @@ -336,11 +345,10 @@ void Speak(how, whom) if (c == EOF) continue; break; } - done = FALSE; /* Don't use ics_prefix; we need to let FICS expand the alias i -> it, but use the real command "i" on ICC */ - strcpy(zipbuf, how); + safeStrCpy(zipbuf, how, sizeof(zipbuf)/sizeof(zipbuf[0])); strcat(zipbuf, " "); if (whom != NULL) { strcat(zipbuf, whom); @@ -372,8 +380,8 @@ void Speak(how, whom) Speak(how, whom); /* tail recursion */ } -int ZippyCalled(str) - char *str; +int +ZippyCalled (char *str) { return ics_handle[0] != NULLCHAR && StrCaseStr(str, ics_handle) != NULL; } @@ -381,27 +389,40 @@ int ZippyCalled(str) static char opp_name[128][32]; static int num_opps=0; -int ZippyControl(buf, i) - char *buf; - int *i; +extern ColorClass curColor; + +static void +SetCurColor (ColorClass color) +{ + curColor = color; +} + +static void +ColorizeEx (ColorClass color, int cont) +{ + if( appData.colorize ) { + Colorize( color, cont ); + SetCurColor( color ); + } +} + +int +ZippyControl (char *buf, int *i) { char *player, *p; char reply[MSG_SIZ]; -#if TRIVIA -#include "trivia.c" -#endif - /* Possibly reject Crafty as opponent */ if (appData.zippyPlay && appData.zippyNoplayCrafty && forwardMostMove < 4 - && looking_at(buf, i, "* kibitzes: Hello from Crafty")) { + && looking_at(buf, i, "* kibitzes: Hello from Crafty")) + { player = StripHighlightAndTitle(star_match[0]); if ((gameMode == IcsPlayingWhite && StrCaseCmp(player, gameInfo.black) == 0) || (gameMode == IcsPlayingBlack && StrCaseCmp(player, gameInfo.white) == 0)) { - sprintf(reply, "%ssay This computer does not play Crafty clones\n%sabort\n%s+noplay %s\n", + snprintf(reply, MSG_SIZ, "%ssay This computer does not play Crafty clones\n%sabort\n%s+noplay %s\n", ics_prefix, ics_prefix, ics_prefix, player); SendToICS(reply); } @@ -416,13 +437,13 @@ int ZippyControl(buf, i) int i; for (i=0;i= num_opps) strcpy(opp_name[num_opps++],star_match[0]); + if (i >= num_opps) safeStrCpy(opp_name[num_opps++],star_match[0], sizeof(opp_name[num_opps])/sizeof(opp_name[num_opps][0])); } if (appData.zippyPlay && looking_at(buf, i, "* * is a computer *")) { int i; for (i=0;i= num_opps) strcpy(opp_name[num_opps++],star_match[1]); + if (i >= num_opps) safeStrCpy(opp_name[num_opps++],star_match[1], sizeof(opp_name[num_opps])/sizeof(opp_name[num_opps][0])); } /* Tells and says */ @@ -431,17 +452,17 @@ int ZippyControl(buf, i) looking_at(buf, i, "* tells you: [automatic message] I chose you"))) { player = StripHighlightAndTitle(star_match[0]); if (appData.zippyBughouse > 1 && first.initDone) { - sprintf(reply, "%spartner %s\n", ics_prefix, player); + snprintf(reply, MSG_SIZ,"%spartner %s\n", ics_prefix, player); SendToICS(reply); if (strcmp(zippyPartner, player) != 0) { - strcpy(zippyPartner, player); - SendToProgram(reply + strlen(ics_prefix), &first); + safeStrCpy(zippyPartner, player, sizeof(zippyPartner)/sizeof(zippyPartner[0])); + SendToProgram(reply + strlen(ics_prefix), &first); } } else if (appData.zippyBughouse > 0) { - sprintf(reply, "%sdecline %s\n", ics_prefix, player); + snprintf(reply, MSG_SIZ, "%sdecline %s\n", ics_prefix, player); SendToICS(reply); } else { - sprintf(reply, "%stell %s This computer cannot play bughouse\n", + snprintf(reply, MSG_SIZ, "%stell %s This computer cannot play bughouse\n", ics_prefix, player); SendToICS(reply); } @@ -451,10 +472,10 @@ int ZippyControl(buf, i) if (appData.zippyPlay && appData.zippyBughouse && first.initDone && looking_at(buf, i, "* agrees to be your partner")) { player = StripHighlightAndTitle(star_match[0]); - sprintf(reply, "partner %s\n", player); + snprintf(reply, MSG_SIZ, "partner %s\n", player); if (strcmp(zippyPartner, player) != 0) { - strcpy(zippyPartner, player); - SendToProgram(reply, &first); + safeStrCpy(zippyPartner, player, sizeof(zippyPartner)/sizeof(zippyPartner[0])); + SendToProgram(reply, &first); } return TRUE; } @@ -485,17 +506,18 @@ int ZippyControl(buf, i) /* This pattern works on FICS but not ICC */ player = StripHighlightAndTitle(star_match[0]); if (strcmp(zippyPartner, player) != 0) { - strcpy(zippyPartner, player); - sprintf(reply, "partner %s\n", player); - SendToProgram(reply, &first); + safeStrCpy(zippyPartner, player, sizeof(zippyPartner)/sizeof(zippyPartner[0])); + snprintf(reply, MSG_SIZ, "partner %s\n", player); + SendToProgram(reply, &first); } - sprintf(reply, "ptell %s\n", star_match[1]); + snprintf(reply, MSG_SIZ, "ptell %s\n", star_match[1]); SendToProgram(reply, &first); return TRUE; } if (looking_at(buf, i, "* tells you: *") || - looking_at(buf, i, "* says: *")) { + looking_at(buf, i, "* says: *")) + { player = StripHighlightAndTitle(star_match[0]); if (appData.zippyPassword[0] != NULLCHAR && strncmp(star_match[1], appData.zippyPassword, @@ -516,7 +538,7 @@ int ZippyControl(buf, i) strlen(appData.zippyWrongPassword)) == 0) { p = star_match[1] + strlen(appData.zippyWrongPassword); while (*p == ' ') p++; - sprintf(reply, "wrong %s\n", player); + snprintf(reply, MSG_SIZ, "wrong %s\n", player); SendToICS(reply); } else if (appData.zippyBughouse && first.initDone && strcmp(player, zippyPartner) == 0) { @@ -525,12 +547,12 @@ int ZippyControl(buf, i) SendToProgram("\n", &first); } else if (strncmp(star_match[1], HI, 6) == 0) { extern char* programVersion; - sprintf(reply, "%stell %s %s\n", + snprintf(reply, MSG_SIZ, "%stell %s %s\n", ics_prefix, player, programVersion); SendToICS(reply); } else if (strncmp(star_match[1], "W0W!! ", 6) == 0) { extern char* programVersion; - sprintf(reply, "%stell %s %s\n", ics_prefix, + snprintf(reply, MSG_SIZ, "%stell %s %s\n", ics_prefix, player, programVersion); SendToICS(reply); } else if (appData.zippyTalk && (((unsigned) random() % 10) < 9)) { @@ -538,20 +560,28 @@ int ZippyControl(buf, i) Speak("tell", player); } } + + ColorizeEx( ColorTell, FALSE ); + return TRUE; } + if( appData.colorize && looking_at(buf, i, "* (*) seeking") ) { + ColorizeEx(ColorSeek, FALSE); + return FALSE; + } + if (looking_at(buf, i, "* spoofs you:")) { player = StripHighlightAndTitle(star_match[0]); - sprintf(reply, "spoofedby %s\n", player); + snprintf(reply, MSG_SIZ, "spoofedby %s\n", player); SendToICS(reply); } + return FALSE; } -int ZippyConverse(buf, i) - char *buf; - int *i; +int +ZippyConverse(char *buf, int *i) { static char lastgreet[MSG_SIZ]; char reply[MSG_SIZ]; @@ -559,19 +589,23 @@ int ZippyConverse(buf, i) /* Shouts and emotes */ if (looking_at(buf, i, "--> * *") || - looking_at(buf, i, "* shouts: *")) { + looking_at(buf, i, "* shouts: *")) + { if (appData.zippyTalk) { char *player = StripHighlightAndTitle(star_match[0]); if (strcmp(player, ics_handle) == 0) { return TRUE; } else if (appData.zippyPinhead[0] != NULLCHAR && StrCaseStr(star_match[1], appData.zippyPinhead) != NULL) { - sprintf(reply, "insult %s\n", player); + snprintf(reply, MSG_SIZ, "insult %s\n", player); SendToICS(reply); } else if (ZippyCalled(star_match[1])) { Speak("shout", NULL); } } + + ColorizeEx(ColorShout, FALSE); + return TRUE; } @@ -582,6 +616,9 @@ int ZippyConverse(buf, i) Speak("kibitz", NULL); } } + + ColorizeEx(ColorKibitz, FALSE); + return TRUE; } @@ -592,6 +629,9 @@ int ZippyConverse(buf, i) Speak("whisper", NULL); } } + + ColorizeEx(ColorKibitz, FALSE); + return TRUE; } @@ -617,7 +657,6 @@ int ZippyConverse(buf, i) /* Channel tells */ oldi = *i; if (looking_at(buf, i, "*(*: *")) { - char *player; char *channel; if (star_match[0][0] == NULLCHAR || strchr(star_match[0], ' ') || @@ -627,7 +666,6 @@ int ZippyConverse(buf, i) return FALSE; } if (appData.zippyTalk) { - player = StripHighlightAndTitle(star_match[0]); channel = strrchr(star_match[1], '('); if (channel == NULL) { channel = star_match[1]; @@ -635,18 +673,13 @@ int ZippyConverse(buf, i) channel++; } channel[strlen(channel)-1] = NULLCHAR; -#if 0 - /* Always tell to the channel (probability 90%) */ - if (strcmp(player, ics_handle) != 0 && - ((unsigned) random() % 10) < 9) { - Speak("tell", channel); - } -#else + /* Tell to the channel only if someone mentions our name */ if (ZippyCalled(star_match[2])) { Speak("tell", channel); } -#endif + + ColorizeEx( atoi(channel) == 1 ? ColorChannel1 : ColorChannel, FALSE ); } return TRUE; } @@ -657,7 +690,7 @@ int ZippyConverse(buf, i) atoi(star_match[0]) != 0) || looking_at(buf, i, "* has left a message for you") || looking_at(buf, i, "* just sent you a message")) { - sprintf(reply, "%smessages\n%sclearmessages *\n", + snprintf(reply, MSG_SIZ, "%smessages\n%sclearmessages *\n", ics_prefix, ics_prefix); SendToICS(reply); return TRUE; @@ -666,8 +699,8 @@ int ZippyConverse(buf, i) if (looking_at(buf, i, "Notification: * has arrived")) { if (((unsigned) random() % 3) == 0) { char *player = StripHighlightAndTitle(star_match[0]); - strcpy(lastgreet, player); - sprintf(reply, "greet %s\n", player); + safeStrCpy(lastgreet, player, sizeof(lastgreet)/sizeof(lastgreet[0])); + snprintf(reply, MSG_SIZ, "greet %s\n", player); SendToICS(reply); Speak("tell", player); } @@ -676,7 +709,7 @@ int ZippyConverse(buf, i) if (looking_at(buf, i, "Notification: * has departed")) { if (((unsigned) random() % 3) == 0) { char *player = StripHighlightAndTitle(star_match[0]); - sprintf(reply, "farewell %s\n", player); + snprintf(reply, MSG_SIZ, "farewell %s\n", player); SendToICS(reply); } } @@ -684,7 +717,7 @@ int ZippyConverse(buf, i) if (looking_at(buf, i, "Not sent -- * is censoring you")) { char *player = StripHighlightAndTitle(star_match[0]); if (strcmp(player, lastgreet) == 0) { - sprintf(reply, "%s-notify %s\n", ics_prefix, player); + snprintf(reply, MSG_SIZ, "%s-notify %s\n", ics_prefix, player); SendToICS(reply); } } @@ -696,8 +729,8 @@ int ZippyConverse(buf, i) return FALSE; } -void ZippyGameStart(white, black) - char *white, *black; +void +ZippyGameStart (char *white, char* black) { if (!first.initDone) { /* Game is starting prematurely. We can't deal with this */ @@ -714,9 +747,8 @@ void ZippyGameStart(white, black) } } -void ZippyGameEnd(result, resultDetails) - ChessMove result; - char *resultDetails; +void +ZippyGameEnd (ChessMove result, char *resultDetails) { if (appData.zippyAcceptOnly[0] == NULLCHAR && appData.zippyGameEnd[0] != NULLCHAR) { @@ -724,47 +756,48 @@ void ZippyGameEnd(result, resultDetails) SendToICS("\n"); } zippyLastGameEnd = time(0); + if(forwardMostMove < appData.zippyShortGame) + safeStrCpy(zippyOffender, zippyLastOpp, sizeof(zippyOffender)/sizeof(zippyOffender[0])); + else + zippyOffender[0] = 0; // [HGM] aborter } /* * Routines to implement Zippy playing chess */ -void ZippyHandleChallenge(srated, swild, sbase, sincrement, opponent) - char *srated, *swild, *sbase, *sincrement, *opponent; +void +ZippyHandleChallenge (char *srated, char *swild, char *sbase, char *sincrement, char *opponent) { char buf[MSG_SIZ]; - int base, increment; - char rated; + int i=0; VariantClass variant; char *varname; - rated = srated[0]; variant = StringToVariant(swild); varname = VariantName(variant); - base = atoi(sbase); - increment = atoi(sincrement); - /* If icsAnalyzeEngine active - we don't accept automatic games */ - if (appData.icsActive) - if (appData.icsEngineAnalyze) return; + /* [DM] If icsAnalyzeEngine active we don't accept automatic games */ + if (appData.icsActive && appData.icsEngineAnalyze) return; /* If desired, you can insert more code here to decline matches based on rated, variant, base, and increment, but it is easier to use the ICS formula feature instead. */ if (variant == VariantLoadable) { - sprintf(buf, + snprintf(buf, MSG_SIZ, "%stell %s This computer can't play wild type %s\n%sdecline %s\n", ics_prefix, opponent, swild, ics_prefix, opponent); SendToICS(buf); return; } - if (StrStr(appData.zippyVariants, varname) == NULL) { - sprintf(buf, + if (StrStr(appData.zippyVariants, varname) == NULL || + ((i=first.protocolVersion) != 1 && StrStr(first.variants, varname) == NULL) /* [HGM] zippyvar */ + ) { + snprintf(buf, MSG_SIZ, "%stell %s This computer can't play %s [%s], only %s\n%sdecline %s\n", - ics_prefix, opponent, swild, varname, appData.zippyVariants, + ics_prefix, opponent, swild, varname, + i ? first.variants : appData.zippyVariants, /* [HGM] zippyvar */ ics_prefix, opponent); SendToICS(buf); return; @@ -783,22 +816,33 @@ void ZippyHandleChallenge(srated, swild, sbase, sincrement, opponent) strcmp(opponent, zippyLastOpp) == 0 && zippyConsecGames >= appData.zippyMaxGames && difftime(time(0), zippyLastGameEnd) < appData.zippyReplayTimeout) { - sprintf(buf, "%stell %s Sorry, you have just played %d consecutive games against %s. To give others a chance, please wait %d seconds or until someone else has played.\n%sdecline %s\n", + snprintf(buf, MSG_SIZ, "%stell %s Sorry, you have just played %d consecutive games against %s. To give others a chance, please wait %d seconds or until someone else has played.\n%sdecline %s\n", ics_prefix, opponent, zippyConsecGames, ics_handle, appData.zippyReplayTimeout, ics_prefix, opponent); SendToICS(buf); return; } + /* [HGM] aborter: opponent is cheater that aborts games he doesn't like on first move. Make him wait */ + if (strcmp(opponent, zippyOffender) == 0 && + difftime(time(0), zippyLastGameEnd) < appData.zippyReplayTimeout) { + snprintf(buf, MSG_SIZ, "%stell %s Sorry, your previous game against %s was rather short. " + " It will wait %d seconds to see if a tougher opponent comes along.\n%sdecline %s\n", + ics_prefix, opponent, ics_handle, + appData.zippyReplayTimeout, ics_prefix, opponent); + SendToICS(buf); + return; + } + /* Engine not yet initialized or still thinking about last game? */ if (!first.initDone || first.lastPing != first.lastPong) { - sprintf(buf, "%stell %s I'm not quite ready for a new game yet; try again soon.\n%sdecline %s\n", + snprintf(buf, MSG_SIZ, "%stell %s I'm not quite ready for a new game yet; try again soon.\n%sdecline %s\n", ics_prefix, opponent, ics_prefix, opponent); SendToICS(buf); return; } - sprintf(buf, "%saccept %s\n", ics_prefix, opponent); + snprintf(buf, MSG_SIZ, "%saccept %s\n", ics_prefix, opponent); SendToICS(buf); if (appData.zippyTalk) { Speak("tell", opponent); @@ -807,9 +851,8 @@ void ZippyHandleChallenge(srated, swild, sbase, sincrement, opponent) /* Accept matches */ -int ZippyMatch(buf, i) - char *buf; - int *i; +int +ZippyMatch (char *buf, int *i) { if (looking_at(buf, i, "* * match * * requested with * (*)")) { @@ -841,7 +884,10 @@ int ZippyMatch(buf, i) if (looking_at(buf, i, "Challenge: * (*) *(*) * * * * Loaded from *")) { /* note: star_match[2] can include "[white] " or "[black] " before our own name. */ - ZippyHandleChallenge(star_match[4], star_match[8], + if(star_match[8] == NULL || star_match[8][0] == 0) // [HGM] chessd: open-source ICS has file on next line + ZippyHandleChallenge(star_match[4], star_match[5], + star_match[6], star_match[7], StripHighlightAndTitle(star_match[0])); + else ZippyHandleChallenge(star_match[4], star_match[8], star_match[6], star_match[7], StripHighlightAndTitle(star_match[0])); return TRUE; @@ -877,20 +923,14 @@ int ZippyMatch(buf, i) return TRUE; } - if (ics_type == ICS_ICC) { - if (looking_at(buf, i, "Your opponent offers you a draw")) { - if (first.sendDrawOffers && first.initDone) - SendToProgram("draw\n", &first); - return TRUE; - } - } else { - if (looking_at(buf, i, "offers you a draw")) { - if (first.sendDrawOffers && first.initDone) { - SendToProgram("draw\n", &first); - } - return TRUE; - } - } + + if (looking_at(buf, i, "Your opponent offers you a draw") || + looking_at(buf, i, "* offers you a draw")) { + if (first.sendDrawOffers && first.initDone) { + SendToProgram("draw\n", &first); + } + return TRUE; + } if (looking_at(buf, i, "requests that the game be aborted") || looking_at(buf, i, "would like to abort")) { @@ -930,13 +970,14 @@ int ZippyMatch(buf, i) /* Initialize chess program with data from the first board * of a new or resumed game. */ -void ZippyFirstBoard(moveNum, basetime, increment) - int moveNum, basetime, increment; +void +ZippyFirstBoard (int moveNum, int basetime, int increment) { char buf[MSG_SIZ]; int w, b; char *opp = (gameMode==IcsPlayingWhite ? gameInfo.black : gameInfo.white); Boolean sentPos = FALSE; + char *bookHit = NULL; // [HGM] book if (!first.initDone) { /* Game is starting prematurely. We can't deal with this */ @@ -949,7 +990,7 @@ void ZippyFirstBoard(moveNum, basetime, increment) /* Send the variant command if needed */ if (gameInfo.variant != VariantNormal) { - sprintf(buf, "variant %s\n", VariantName(gameInfo.variant)); + snprintf(buf, MSG_SIZ, "variant %s\n", VariantName(gameInfo.variant)); SendToProgram(buf, &first); } @@ -960,7 +1001,7 @@ void ZippyFirstBoard(moveNum, basetime, increment) sentPos = TRUE; } - sprintf(buf, "level 0 %d %d\n", basetime, increment); + snprintf(buf, MSG_SIZ, "level 0 %d %d\n", basetime, increment); SendToProgram(buf, &first); /* Count consecutive games from one opponent */ @@ -968,7 +1009,7 @@ void ZippyFirstBoard(moveNum, basetime, increment) zippyConsecGames++; } else { zippyConsecGames = 1; - strcpy(zippyLastOpp, opp); + safeStrCpy(zippyLastOpp, opp, sizeof(zippyLastOpp)/sizeof(zippyLastOpp[0])); } /* Send the "computer" command if the opponent is in the list @@ -988,11 +1029,11 @@ void ZippyFirstBoard(moveNum, basetime, increment) firstMove = FALSE; if (gameMode == IcsPlayingWhite) { if (first.sendName) { - sprintf(buf, "name %s\n", gameInfo.black); + snprintf(buf, MSG_SIZ, "name %s\n", gameInfo.black); SendToProgram(buf, &first); } - strcpy(ics_handle, gameInfo.white); - sprintf(buf, "rating %d %d\n", w, b); + safeStrCpy(ics_handle, gameInfo.white, MSG_SIZ); + snprintf(buf, MSG_SIZ, "rating %d %d\n", w, b); SendToProgram(buf, &first); if (sentPos) { /* Position sent above, engine is in force mode */ @@ -1007,7 +1048,7 @@ void ZippyFirstBoard(moveNum, basetime, increment) SendTimeRemaining(&first, TRUE); } } - SendToProgram("go\n", &first); + bookHit = SendMoveToBookUser(forwardMostMove-1, &first, TRUE); // [HGM] book: send go or retrieve book move } else { /* Engine's opponent is on move now */ if (first.usePlayother) { @@ -1033,16 +1074,17 @@ void ZippyFirstBoard(moveNum, basetime, increment) SendTimeRemaining(&first, TRUE); } } - SendToProgram("go\n", &first); +// SendToProgram("go\n", &first); + bookHit = SendMoveToBookUser(forwardMostMove-1, &first, TRUE); // [HGM] book: send go or retrieve book move } } } else if (gameMode == IcsPlayingBlack) { if (first.sendName) { - sprintf(buf, "name %s\n", gameInfo.white); + snprintf(buf, MSG_SIZ, "name %s\n", gameInfo.white); SendToProgram(buf, &first); } - strcpy(ics_handle, gameInfo.black); - sprintf(buf, "rating %d %d\n", b, w); + safeStrCpy(ics_handle, gameInfo.black, MSG_SIZ); + snprintf(buf, MSG_SIZ, "rating %d %d\n", b, w); SendToProgram(buf, &first); if (sentPos) { /* Position sent above, engine is in force mode */ @@ -1057,7 +1099,8 @@ void ZippyFirstBoard(moveNum, basetime, increment) SendTimeRemaining(&first, FALSE); } } - SendToProgram("go\n", &first); +// SendToProgram("go\n", &first); + bookHit = SendMoveToBookUser(forwardMostMove-1, &first, TRUE); // [HGM] book: send go or retrieve book move } else { /* Engine's opponent is on move now */ if (first.usePlayother) { @@ -1075,16 +1118,27 @@ void ZippyFirstBoard(moveNum, basetime, increment) /* Nothing needs to be done here */ } } + + if(bookHit) { // [HGM] book: simulate book reply + static char bookMove[MSG_SIZ]; // a bit generous? + + programStats.depth = programStats.nodes = programStats.time = + programStats.score = programStats.got_only_move = 0; + sprintf(programStats.movelist, "%s (xbook)", bookHit); + + safeStrCpy(bookMove, "move ", sizeof(bookMove)/sizeof(bookMove[0])); + strcat(bookMove, bookHit); + HandleMachineMove(bookMove, &first); + } } void -ZippyHoldings(white_holding, black_holding, new_piece) - char *white_holding, *black_holding, *new_piece; +ZippyHoldings (char *white_holding, char *black_holding, char *new_piece) { char buf[MSG_SIZ]; if (gameMode != IcsPlayingBlack && gameMode != IcsPlayingWhite) return; - sprintf(buf, "holding [%s] [%s] %s\n", + snprintf(buf, MSG_SIZ, "holding [%s] [%s] %s\n", white_holding, black_holding, new_piece); SendToProgram(buf, &first); }