X-Git-Url: https://git.cameronkatri.com/bsdgames-darwin.git/blobdiff_plain/88eff08098072c4b923af3a7180b14d6dfcf66ef..41ea0dbfd0fa937c96c965324e8f01aa9864130e:/gomoku/main.c diff --git a/gomoku/main.c b/gomoku/main.c index 3d5d862b..4d9acb26 100644 --- a/gomoku/main.c +++ b/gomoku/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.10 2000/05/08 07:56:03 mycroft Exp $ */ +/* $NetBSD: main.c,v 1.27 2016/06/12 02:15:26 dholland Exp $ */ /* * Copyright (c) 1994 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -38,21 +34,23 @@ #include #ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1994\n\ - The Regents of the University of California. All rights reserved.\n"); +__COPYRIGHT("@(#) Copyright (c) 1994\ + The Regents of the University of California. All rights reserved."); #endif /* not lint */ #ifndef lint #if 0 static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 5/4/95"; #else -__RCSID("$NetBSD: main.c,v 1.10 2000/05/08 07:56:03 mycroft Exp $"); +__RCSID("$NetBSD: main.c,v 1.27 2016/06/12 02:15:26 dholland Exp $"); #endif #endif /* not lint */ #include #include +#include #include +#include #include #include #include @@ -66,13 +64,13 @@ __RCSID("$NetBSD: main.c,v 1.10 2000/05/08 07:56:03 mycroft Exp $"); int interactive = 1; /* true if interactive */ int debug; /* true if debugging */ -int test; /* both moves come from 1: input, 2: computer */ -char *prog; /* name of program */ -FILE *debugfp; /* file for debug output */ -FILE *inputfp; /* file for debug input */ +static int test; /* both moves come from 1: input, 2: computer */ +static char *prog; /* name of program */ +static char user[LOGIN_NAME_MAX]; /* name of player */ +static FILE *debugfp; /* file for debug output */ +static FILE *inputfp; /* file for debug input */ const char pdir[4] = "-\\|/"; -char fmtbuf[128]; struct spotstr board[BAREA]; /* info for board */ struct combostr frames[FAREA]; /* storage for all frames */ @@ -83,24 +81,30 @@ int movelog[BSZ * BSZ]; /* log of all the moves */ int movenum; /* current move number */ const char *plyr[2]; /* who's who */ -int main __P((int, char *[])); +static int readinput(FILE *); +static void misclog(const char *, ...) __printflike(1, 2); +static void quit(void) __dead; +static void quitsig(int) __dead; int -main(argc, argv) - int argc; - char **argv; +main(int argc, char **argv) { char buf[128]; + char fname[PATH_MAX]; + char *tmp; int color, curmove, i, ch; int input[2]; - static const char *const fmt[2] = { - "%3d %-6s", - "%3d %-6s" - }; /* Revoke setgid privileges */ setgid(getgid()); + tmp = getlogin(); + if (tmp) { + strlcpy(user, tmp, sizeof(user)); + } else { + strcpy(user, "you"); + } + color = curmove = 0; prog = strrchr(argv[0], '/'); @@ -121,10 +125,10 @@ main(argc, argv) if ((debugfp = fopen(optarg, "w")) == NULL) err(1, "%s", optarg); break; - case 'u': /* testing: user verses user */ + case 'u': /* testing: user versus user */ test = 1; break; - case 'c': /* testing: computer verses computer */ + case 'c': /* testing: computer versus computer */ test = 2; break; } @@ -137,11 +141,7 @@ main(argc, argv) } if (!debug) -#ifdef SVR4 - srand(time(0)); -#else srandom(time(0)); -#endif if (interactive) cursinit(); /* initialize curses */ again: @@ -157,35 +157,38 @@ again: #endif if (inputfp == NULL && test == 0) { + move(BSZ3, 0); + printw("Black moves first. "); + ask("(B)lack or (W)hite? "); for (;;) { - ask("black or white? "); - getline(buf, sizeof(buf)); - if (buf[0] == 'b' || buf[0] == 'B') { + ch = get_key(NULL); + if (ch == 'b' || ch == 'B') { color = BLACK; break; } - if (buf[0] == 'w' || buf[0] == 'W') { + if (ch == 'w' || ch == 'W') { color = WHITE; break; } - move(22, 0); - printw("Black moves first. Please enter `black' or `white'\n"); + if (ch == 'q' || ch == 'Q') { + quit(); + } + beep(); + ask("Please choose (B)lack or (W)hite: "); } - move(22, 0); + move(BSZ3, 0); clrtoeol(); } } else { setbuf(stdout, 0); - getline(buf, sizeof(buf)); + get_line(buf, sizeof(buf)); if (strcmp(buf, "black") == 0) color = BLACK; else if (strcmp(buf, "white") == 0) color = WHITE; else { - sprintf(fmtbuf, - "Huh? Expected `black' or `white', got `%s'\n", + panic("Huh? Expected `black' or `white', got `%s'\n", buf); - panic(fmtbuf); } } @@ -194,25 +197,25 @@ again: input[WHITE] = INPUTF; } else { switch (test) { - case 0: /* user verses program */ + case 0: /* user versus program */ input[color] = USER; input[!color] = PROGRAM; break; - case 1: /* user verses user */ + case 1: /* user versus user */ input[BLACK] = USER; input[WHITE] = USER; break; - case 2: /* program verses program */ + case 2: /* program versus program */ input[BLACK] = PROGRAM; input[WHITE] = PROGRAM; break; } } if (interactive) { - plyr[BLACK] = input[BLACK] == USER ? "you" : prog; - plyr[WHITE] = input[WHITE] == USER ? "you" : prog; + plyr[BLACK] = input[BLACK] == USER ? user : prog; + plyr[WHITE] = input[WHITE] == USER ? user : prog; bdwho(1); } @@ -224,45 +227,38 @@ again: if (curmove != ILLEGAL) break; switch (test) { - case 0: /* user verses program */ + case 0: /* user versus program */ input[color] = USER; input[!color] = PROGRAM; break; - case 1: /* user verses user */ + case 1: /* user versus user */ input[BLACK] = USER; input[WHITE] = USER; break; - case 2: /* program verses program */ + case 2: /* program versus program */ input[BLACK] = PROGRAM; input[WHITE] = PROGRAM; break; } - plyr[BLACK] = input[BLACK] == USER ? "you" : prog; - plyr[WHITE] = input[WHITE] == USER ? "you" : prog; + plyr[BLACK] = input[BLACK] == USER ? user : prog; + plyr[WHITE] = input[WHITE] == USER ? user : prog; bdwho(1); goto top; case USER: /* input comes from standard input */ getinput: - if (interactive) - ask("move? "); - if (!getline(buf, sizeof(buf))) { - curmove = RESIGN; - break; - } - if (buf[0] == '\0') - goto getinput; - curmove = ctos(buf); if (interactive) { + ask("Select move, (S)ave or (Q)uit."); + curmove = get_coord(); if (curmove == SAVE) { FILE *fp; - ask("save file name? "); - (void)getline(buf, sizeof(buf)); - if ((fp = fopen(buf, "w")) == NULL) { - glog("cannot create save file"); + ask("Save file name? "); + (void)get_line(fname, sizeof(fname)); + if ((fp = fopen(fname, "w")) == NULL) { + misclog("cannot create save file"); goto getinput; } for (i = 0; i < movenum - 1; i++) @@ -273,19 +269,30 @@ again: } if (curmove != RESIGN && board[curmove].s_occ != EMPTY) { - glog("Illegal move"); + /*misclog("Illegal move");*/ + beep(); goto getinput; } + } else { + if (!get_line(buf, sizeof(buf))) { + curmove = RESIGN; + break; + } + if (buf[0] == '\0') + goto getinput; + curmove = ctos(buf); } break; case PROGRAM: /* input comes from the program */ + if (interactive) + ask("Thinking..."); curmove = pickmove(color); break; } if (interactive) { - sprintf(fmtbuf, fmt[color], movenum, stoc(curmove)); - glog(fmtbuf); + misclog("%3d%s%-6s", movenum, color ? " " : " ", + stoc(curmove)); } if ((i = makemove(color, curmove)) != MOVEOK) break; @@ -293,16 +300,18 @@ again: bdisp(); } if (interactive) { - move(22, 0); + move(BSZ3, 0); switch (i) { case WIN: if (input[color] == PROGRAM) addstr("Ha ha, I won"); + else if (input[0] == USER && input[1] == USER) + addstr("Well, you won (and lost)"); else addstr("Rats! you won"); break; case TIE: - addstr("Wow! its a tie"); + addstr("Wow! It's a tie"); break; case ILLEGAL: addstr("Illegal move"); @@ -312,17 +321,17 @@ again: bdisp(); if (i != RESIGN) { replay: - ask("replay? "); - if (getline(buf, sizeof(buf)) && - (buf[0] == 'y' || buf[0] == 'Y')) + ask("Play again? "); + ch = get_key("YyNnQqSs"); + if (ch == 'Y' || ch == 'y') goto again; - if (strcmp(buf, "save") == 0) { + if (ch == 'S') { FILE *fp; - ask("save file name? "); - (void)getline(buf, sizeof(buf)); - if ((fp = fopen(buf, "w")) == NULL) { - glog("cannot create save file"); + ask("Save file name? "); + (void)get_line(fname, sizeof(fname)); + if ((fp = fopen(fname, "w")) == NULL) { + misclog("cannot create save file"); goto replay; } for (i = 0; i < movenum - 1; i++) @@ -338,18 +347,18 @@ again: return(0); } -int -readinput(fp) - FILE *fp; +static int +readinput(FILE *fp) { - char *cp; int c; + char buf[128]; + size_t pos; - cp = fmtbuf; - while ((c = getc(fp)) != EOF && c != '\n') - *cp++ = c; - *cp = '\0'; - return (ctos(fmtbuf)); + pos = 0; + while ((c = getc(fp)) != EOF && c != '\n' && pos < sizeof(buf) - 1) + buf[pos++] = c; + buf[pos] = '\0'; + return ctos(buf); } #ifdef DEBUG @@ -357,31 +366,31 @@ readinput(fp) * Handle strange situations. */ void -whatsup(signum) - int signum; +whatsup(int signum) { - int i, pnum, n, s1, s2, d1, d2; + int i, n, s1, s2, d1, d2; struct spotstr *sp; FILE *fp; char *str; struct elist *ep; struct combostr *cbp; + char input[128]; + char tmp[128]; if (!interactive) quit(); top: - ask("cmd? "); - if (!getline(fmtbuf, sizeof(fmtbuf))) + ask("debug command: "); + if (!get_line(input, sizeof(input))) quit(); - switch (*fmtbuf) { + switch (*input) { case '\0': goto top; case 'q': /* conservative quit */ quit(); case 'd': /* set debug level */ - debug = fmtbuf[1] - '0'; - sprintf(fmtbuf, "Debug set to %d", debug); - dlog(fmtbuf); + debug = input[1] - '0'; + debuglog("Debug set to %d", debug); sleep(1); case 'c': break; @@ -393,10 +402,9 @@ top: } goto top; case 's': /* suggest a move */ - i = fmtbuf[1] == 'b' ? BLACK : WHITE; - sprintf(fmtbuf, "suggest %c %s", i == BLACK ? 'B' : 'W', + i = input[1] == 'b' ? BLACK : WHITE; + debuglog("suggest %c %s", i == BLACK ? 'B' : 'W', stoc(pickmove(i))); - dlog(fmtbuf); goto top; case 'f': /* go forward a move */ board[movelog[movenum - 1]].s_occ = movenum & 1 ? BLACK : WHITE; @@ -404,12 +412,12 @@ top: bdisp(); goto top; case 'l': /* print move history */ - if (fmtbuf[1] == '\0') { + if (input[1] == '\0') { for (i = 0; i < movenum - 1; i++) - dlog(stoc(movelog[i])); + debuglog("%s", stoc(movelog[i])); goto top; } - if ((fp = fopen(fmtbuf + 1, "w")) == NULL) + if ((fp = fopen(input + 1, "w")) == NULL) goto top; for (i = 0; i < movenum - 1; i++) { fprintf(fp, "%s", stoc(movelog[i])); @@ -422,14 +430,17 @@ top: fclose(fp); goto top; case 'o': + /* avoid use w/o initialization on invalid input */ + d1 = s1 = 0; + n = 0; - for (str = fmtbuf + 1; *str; str++) + for (str = input + 1; *str; str++) if (*str == ',') { for (d1 = 0; d1 < 4; d1++) if (str[-1] == pdir[d1]) break; str[-1] = '\0'; - sp = &board[s1 = ctos(fmtbuf + 1)]; + sp = &board[s1 = ctos(input + 1)]; n = (sp->s_frame[d1] - frames) * FAREA; *str++ = '\0'; break; @@ -441,31 +452,25 @@ top: if (str[-1] == pdir[d2]) break; n += sp->s_frame[d2] - frames; - str = fmtbuf; - sprintf(str, "overlap %s%c,", stoc(s1), pdir[d1]); - str += strlen(str); - sprintf(str, "%s%c = %x", stoc(s2), pdir[d2], overlap[n]); - dlog(fmtbuf); + debuglog("overlap %s%c,%s%c = %x", stoc(s1), pdir[d1], + stoc(s2), pdir[d2], overlap[n]); goto top; case 'p': - sp = &board[i = ctos(fmtbuf + 1)]; - sprintf(fmtbuf, "V %s %x/%d %d %x/%d %d %d %x", stoc(i), + sp = &board[i = ctos(input + 1)]; + debuglog("V %s %x/%d %d %x/%d %d %d %x", stoc(i), sp->s_combo[BLACK].s, sp->s_level[BLACK], sp->s_nforce[BLACK], sp->s_combo[WHITE].s, sp->s_level[WHITE], - sp->s_nforce[WHITE], sp->s_wval, sp->s_flg); - dlog(fmtbuf); - sprintf(fmtbuf, "FB %s %x %x %x %x", stoc(i), + sp->s_nforce[WHITE], sp->s_wval, sp->s_flags); + debuglog("FB %s %x %x %x %x", stoc(i), sp->s_fval[BLACK][0].s, sp->s_fval[BLACK][1].s, sp->s_fval[BLACK][2].s, sp->s_fval[BLACK][3].s); - dlog(fmtbuf); - sprintf(fmtbuf, "FW %s %x %x %x %x", stoc(i), + debuglog("FW %s %x %x %x %x", stoc(i), sp->s_fval[WHITE][0].s, sp->s_fval[WHITE][1].s, sp->s_fval[WHITE][2].s, sp->s_fval[WHITE][3].s); - dlog(fmtbuf); goto top; case 'e': /* e {b|w} [0-9] spot */ - str = fmtbuf + 1; + str = input + 1; if (*str >= '0' && *str <= '9') n = *str++ - '0'; else @@ -479,17 +484,16 @@ top: if (cbp->c_nframes != n) break; } - printcombo(cbp, fmtbuf); - dlog(fmtbuf); + printcombo(cbp, tmp, sizeof(tmp)); + debuglog("%s", tmp); } goto top; default: -syntax: - dlog("Options are:"); - dlog("q - quit"); - dlog("c - continue"); - dlog("d# - set debug level to #"); - dlog("p# - print values at #"); + debuglog("Options are:"); + debuglog("q - quit"); + debuglog("c - continue"); + debuglog("d# - set debug level to #"); + debuglog("p# - print values at #"); goto top; } } @@ -499,33 +503,43 @@ syntax: * Display debug info. */ void -dlog(str) - const char *str; +debuglog(const char *fmt, ...) { + va_list ap; + char buf[128]; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); if (debugfp) - fprintf(debugfp, "%s\n", str); + fprintf(debugfp, "%s\n", buf); if (interactive) - dislog(str); + dislog(buf); else - fprintf(stderr, "%s\n", str); + fprintf(stderr, "%s\n", buf); } -void -glog(str) - const char *str; +static void +misclog(const char *fmt, ...) { + va_list ap; + char buf[128]; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); if (debugfp) - fprintf(debugfp, "%s\n", str); + fprintf(debugfp, "%s\n", buf); if (interactive) - dislog(str); + dislog(buf); else - printf("%s\n", str); + printf("%s\n", buf); } -void -quit() +static void +quit(void) { if (interactive) { bdisp(); /* show final board */ @@ -534,9 +548,8 @@ quit() exit(0); } -void -quitsig(dummy) - int dummy __attribute__((__unused__)); +static void +quitsig(int dummy __unused) { quit(); } @@ -545,10 +558,21 @@ quitsig(dummy) * Die gracefully. */ void -panic(str) - const char *str; +panic(const char *fmt, ...) { - fprintf(stderr, "%s: %s\n", prog, str); - fputs("resign\n", stdout); - quit(); + va_list ap; + + if (interactive) { + bdisp(); + cursfini(); + } + + fprintf(stderr, "%s: ", prog); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + + fputs("I resign\n", stdout); + exit(1); }