* zippy.c -- Implements Zippy the Pinhead chess player on ICS in XBoard
*
* Copyright 1991 by Digital Equipment Corporation, Maynard,
- * Massachusetts.
+ * Massachusetts.
*
* Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,
- * 2007, 2008, 2009 Free Software Foundation, Inc.
+ * 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
*
* Enhancements Copyright 2005 Alessandro Scotti
*
extern void mysrandom(unsigned int seed);
extern int myrandom(void);
-void ZippyInit()
+void
+ZippyInit ()
{
char *p;
if ( p != NULL ) {
appData.zippyAcceptOnly = p;
}
-
+
/* Should Zippy use "i" command? */
/* Defaults to 1=true */
p = getenv("ZIPPYUSEI");
if (p != NULL) {
appData.zippyVariants = p;
}
- strcpy(first.variants, appData.zippyVariants);
+ safeStrCpy(first.variants, appData.zippyVariants, sizeof(first.variants)/sizeof(first.variants[0]));
srandom(time(NULL));
}
*/
-char *swifties[] = {
+char *swifties[] = {
"i acclaims:", "i admonishes:", "i advertises:", "i advises:",
"i advocates:", "i affirms:", "i alleges:", "i anathematizes:",
"i animadverts:", "i announces:", "i apostrophizes:",
"i hosannas:", "i howls:", "i hums:", "i hypothecates:",
"i hypothesizes:", "i imagines:", "i implies:", "i implores:",
"i imprecates:", "i indicates:", "i infers:",
- "i informs everyone:", "i instructs:", "i interjects:",
+ "i informs everyone:", "i instructs:", "i interjects:",
"i interposes:", "i intimates:", "i intones:", "i introspects:",
"i inveighs:", "i jabbers:", "i japes:", "i jests:", "i jibes:",
"i jives:", "i jokes:", "i joshes:", "i keens:", "i laments:",
#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;
char *p;
int c, speechlen;
Boolean done;
-
+
if (strcmp(how, "shout") == 0) {
now = time((time_t *) NULL);
if (now - lastShout < 1*60) return;
}
fstat(fileno(zipfile), &zipstat);
}
-
+
for (;;) {
fseek(zipfile, (unsigned) random() % zipstat.st_size, 0);
do {
/* 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);
Speak(how, whom); /* tail recursion */
}
-int ZippyCalled(str)
- char *str;
+int
+ZippyCalled (char *str)
{
return ics_handle[0] != NULLCHAR && StrCaseStr(str, ics_handle) != NULL;
}
extern ColorClass curColor;
-static void SetCurColor( ColorClass color )
+static void
+SetCurColor (ColorClass color)
{
curColor = color;
}
-static void ColorizeEx( ColorClass color, int cont )
+static void
+ColorizeEx (ColorClass color, int cont)
{
if( appData.colorize ) {
Colorize( color, cont );
}
}
-int ZippyControl(buf, i)
- char *buf;
- int *i;
+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 &&
(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);
}
/* If this is a computer, save the name. Then later, once the */
/* game is really started, we will send the "computer" notice to */
- /* the engine. */
+ /* the engine. */
if (appData.zippyPlay &&
looking_at(buf, i, "* is in the computer list")) {
int i;
for (i=0;i<num_opps;i++)
if (!strcmp(opp_name[i],star_match[0])) break;
- if (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;i++)
if (!strcmp(opp_name[i],star_match[1])) break;
- if (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 */
- if (appData.zippyPlay &&
+ if (appData.zippyPlay &&
(looking_at(buf, i, "* offers to be your bughouse partner") ||
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);
}
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;
}
/* 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 &&
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) {
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)) {
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];
/* 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]);
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);
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 );
}
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;
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);
}
- }
+ }
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);
}
- }
+ }
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);
}
- }
+ }
if (looking_at(buf, i, "command is currently turned off")) {
appData.zippyUseI = 0;
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 */
}
}
-void ZippyGameEnd(result, resultDetails)
- ChessMove result;
- char *resultDetails;
+void
+ZippyGameEnd (ChessMove result, char *resultDetails)
{
if (appData.zippyAcceptOnly[0] == NULLCHAR &&
appData.zippyGameEnd[0] != NULLCHAR) {
SendToICS("\n");
}
zippyLastGameEnd = time(0);
- if(forwardMostMove < appData.zippyShortGame)
- strcpy(zippyOffender, zippyLastOpp); else zippyOffender[0] = 0; // [HGM] aborter
+ 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, i=0;
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);
if (StrStr(appData.zippyVariants, varname) == NULL ||
((i=first.protocolVersion) != 1 && StrStr(first.variants, varname) == NULL) /* [HGM] zippyvar */
) {
- sprintf(buf,
+ snprintf(buf, MSG_SIZ,
"%stell %s This computer can't play %s [%s], only %s\n%sdecline %s\n",
- ics_prefix, opponent, swild, varname,
+ ics_prefix, opponent, swild, varname,
i ? first.variants : appData.zippyVariants, /* [HGM] zippyvar */
ics_prefix, opponent);
SendToICS(buf);
/* Yes, and this isn't him. Ignore challenge. */
return;
}
-
+
/* Too many consecutive games with same opponent? If so, make him
wait until someone else has played or a timeout has elapsed. */
if (appData.zippyMaxGames &&
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);
/* [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. "
+ 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);
/* 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);
/* Accept matches */
-int ZippyMatch(buf, i)
- char *buf;
- int *i;
+int
+ZippyMatch (char *buf, int *i)
{
if (looking_at(buf, i, "* * match * * requested with * (*)")) {
}
- 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 (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")) {
return FALSE;
}
-/* Initialize chess program with data from the first board
+/* 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;
/* 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);
}
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 */
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
message from ICS." Send 0 in that case */
w = (gameInfo.whiteRating >= 0) ? gameInfo.whiteRating : 0;
b = (gameInfo.blackRating >= 0) ? gameInfo.blackRating : 0;
-
+
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 */
}
} 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 */
} else {
/* Position not sent above, move list might be sent later */
/* 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.depth = programStats.nodes = programStats.time =
programStats.score = programStats.got_only_move = 0;
sprintf(programStats.movelist, "%s (xbook)", bookHit);
- strcpy(bookMove, "move ");
+ 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);
}