X-Git-Url: http://winboard.nl/cgi-bin?p=xboard.git;a=blobdiff_plain;f=zippy.c;h=2698ac5f6f2a9503184bf673b29b7ef2096ea784;hp=b1a7fc84dfcded89d8c8db042079c2c5f730b9e3;hb=d9a803f2e64634ff75f89b7e3b0a65ac085f0e36;hpb=05bc30b15e31c427ce208495a889e9ff36e6642b diff --git a/zippy.c b/zippy.c index b1a7fc8..2698ac5 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 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,11 +93,18 @@ 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() { char *p; @@ -227,7 +239,8 @@ char *swifties[] = { "i enthuses:", "i entreats:", "i enunciates:", "i eulogizes:", "i exclaims:", "i execrates:", "i exhorts:", "i expatiates:", "i explains:", "i explicates:", "i explodes:", "i exposes:", - "i exposits:", "i expounds:", "i expresses:", "i extols:", + "i exposits:", "i expostulates: ", + "i expounds:", "i expresses:", "i extols:", "i exults:", "i fantasizes:", "i fibs:", "i filibusters:", "i flatters:", "i flutes:", "i fools:", "i free-associates:", "i fulminates:", "i gabbles:", "i gabs:", "i gasps:", @@ -308,7 +321,8 @@ void Speak(how, whom) if (now - lastShout < 1*60) return; lastShout = now; if (appData.zippyUseI) { - how = swifties[random() % (sizeof(swifties)/sizeof(char *))]; + how = swifties[(unsigned) random() % + (sizeof(swifties)/sizeof(char *))]; } } @@ -322,7 +336,7 @@ void Speak(how, whom) } for (;;) { - fseek(zipfile, random() % zipstat.st_size, 0); + fseek(zipfile, (unsigned) random() % zipstat.st_size, 0); do { c = getc(zipfile); } while (c != NULLCHAR && c != '^' && c != EOF); @@ -376,6 +390,21 @@ int ZippyCalled(str) static char opp_name[128][32]; static int num_opps=0; +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(buf, i) char *buf; int *i; @@ -383,13 +412,10 @@ int ZippyControl(buf, 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) || @@ -490,7 +516,8 @@ int ZippyControl(buf, i) } 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, @@ -528,19 +555,28 @@ int ZippyControl(buf, i) sprintf(reply, "%stell %s %s\n", ics_prefix, player, programVersion); SendToICS(reply); - } else if (appData.zippyTalk && ((random() % 10) < 9)) { + } else if (appData.zippyTalk && (((unsigned) random() % 10) < 9)) { if (strcmp(player, ics_handle) != 0) { 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); SendToICS(reply); } + return FALSE; } @@ -554,7 +590,8 @@ 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) { @@ -567,26 +604,35 @@ int ZippyConverse(buf, i) Speak("shout", NULL); } } + + ColorizeEx(ColorShout, FALSE); + return TRUE; } if (looking_at(buf, i, "* kibitzes: *")) { - if (appData.zippyTalk && (random() % 10) < 9) { + if (appData.zippyTalk && ((unsigned) random() % 10) < 9) { char *player = StripHighlightAndTitle(star_match[0]); if (strcmp(player, ics_handle) != 0) { Speak("kibitz", NULL); } } + + ColorizeEx(ColorKibitz, FALSE); + return TRUE; } if (looking_at(buf, i, "* whispers: *")) { - if (appData.zippyTalk && (random() % 10) < 9) { + if (appData.zippyTalk && ((unsigned) random() % 10) < 9) { char *player = StripHighlightAndTitle(star_match[0]); if (strcmp(player, ics_handle) != 0) { Speak("whisper", NULL); } } + + ColorizeEx(ColorKibitz, FALSE); + return TRUE; } @@ -598,7 +644,7 @@ int ZippyConverse(buf, i) char *player = StripHighlightAndTitle(star_match[0]); if (strcmp(player, ics_handle) != 0) { - if ((random() % 10) < 9) + if (((unsigned) random() % 10) < 9) Speak("message", player); f = fopen("zippy.messagelog", "a"); fprintf(f, "%s (%s:%s): %s\n", player, @@ -630,17 +676,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 && (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; } @@ -658,7 +700,7 @@ int ZippyConverse(buf, i) } if (looking_at(buf, i, "Notification: * has arrived")) { - if ((random() % 3) == 0) { + if (((unsigned) random() % 3) == 0) { char *player = StripHighlightAndTitle(star_match[0]); strcpy(lastgreet, player); sprintf(reply, "greet %s\n", player); @@ -668,7 +710,7 @@ int ZippyConverse(buf, i) } if (looking_at(buf, i, "Notification: * has departed")) { - if ((random() % 3) == 0) { + if (((unsigned) random() % 3) == 0) { char *player = StripHighlightAndTitle(star_match[0]); sprintf(reply, "farewell %s\n", player); SendToICS(reply); @@ -718,6 +760,8 @@ void ZippyGameEnd(result, resultDetails) SendToICS("\n"); } zippyLastGameEnd = time(0); + if(forwardMostMove < appData.zippyShortGame) + strcpy(zippyOffender, zippyLastOpp); else zippyOffender[0] = 0; // [HGM] aborter } /* @@ -728,7 +772,7 @@ void ZippyHandleChallenge(srated, swild, sbase, sincrement, opponent) char *srated, *swild, *sbase, *sincrement, *opponent; { char buf[MSG_SIZ]; - int base, increment; + int base, increment, i=0; char rated; VariantClass variant; char *varname; @@ -739,6 +783,9 @@ void ZippyHandleChallenge(srated, swild, sbase, sincrement, opponent) base = atoi(sbase); increment = atoi(sincrement); + /* [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. */ @@ -750,10 +797,13 @@ void ZippyHandleChallenge(srated, swild, sbase, sincrement, opponent) SendToICS(buf); return; } - if (StrStr(appData.zippyVariants, varname) == NULL) { + if (StrStr(appData.zippyVariants, varname) == NULL || + ((i=first.protocolVersion) != 1 && StrStr(first.variants, varname) == NULL) /* [HGM] zippyvar */ + ) { sprintf(buf, "%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; @@ -779,6 +829,17 @@ void ZippyHandleChallenge(srated, swild, sbase, sincrement, opponent) 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) { + sprintf(buf, "%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", @@ -830,7 +891,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; @@ -866,11 +930,20 @@ int ZippyMatch(buf, i) return TRUE; } - if (looking_at(buf, i, "offers you a draw")) { - if (first.sendDrawOffers && first.initDone) { - SendToProgram("draw\n", &first); - } - return TRUE; + + if (ics_type == ICS_ICC) { // [DM] + 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, "requests that the game be aborted") || @@ -918,6 +991,7 @@ void ZippyFirstBoard(moveNum, basetime, increment) 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 */ @@ -988,7 +1062,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) { @@ -1014,7 +1088,8 @@ 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) { @@ -1038,7 +1113,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) { @@ -1056,6 +1132,18 @@ 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); + + strcpy(bookMove, "move "); + strcat(bookMove, bookHit); + HandleMachineMove(bookMove, &first); + } }