diff options
-rw-r--r-- | games/gomoku/bdinit.c | 6 | ||||
-rw-r--r-- | games/gomoku/bdisp.c | 176 | ||||
-rw-r--r-- | games/gomoku/gomoku.6 | 29 | ||||
-rw-r--r-- | games/gomoku/gomoku.h | 87 | ||||
-rw-r--r-- | games/gomoku/main.c | 91 | ||||
-rw-r--r-- | games/gomoku/makemove.c | 6 | ||||
-rw-r--r-- | games/gomoku/pickmove.c | 6 | ||||
-rw-r--r-- | games/gomoku/stoc.c | 6 |
8 files changed, 310 insertions, 97 deletions
diff --git a/games/gomoku/bdinit.c b/games/gomoku/bdinit.c index 475fa04dbb1..69f9fa5d2e5 100644 --- a/games/gomoku/bdinit.c +++ b/games/gomoku/bdinit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bdinit.c,v 1.2 1996/12/21 21:17:49 tholo Exp $ */ +/* $OpenBSD: bdinit.c,v 1.3 1998/03/26 21:16:43 pjanzen Exp $ */ /* * Copyright (c) 1994 * The Regents of the University of California. All rights reserved. @@ -36,7 +36,11 @@ */ #ifndef lint +#if 0 static char sccsid[] = "@(#)bdinit.c 8.2 (Berkeley) 5/3/95"; +#else +static char rcsid[] = "$OpenBSD: bdinit.c,v 1.3 1998/03/26 21:16:43 pjanzen Exp $"; +#endif #endif /* not lint */ #include "gomoku.h" diff --git a/games/gomoku/bdisp.c b/games/gomoku/bdisp.c index d696a5d84e4..30c6474d4d8 100644 --- a/games/gomoku/bdisp.c +++ b/games/gomoku/bdisp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bdisp.c,v 1.3 1996/12/21 21:17:49 tholo Exp $ */ +/* $OpenBSD: bdisp.c,v 1.4 1998/03/26 21:16:45 pjanzen Exp $ */ /* * Copyright (c) 1994 * The Regents of the University of California. All rights reserved. @@ -36,12 +36,17 @@ */ #ifndef lint +#if 0 static char sccsid[] = "@(#)bdisp.c 8.2 (Berkeley) 5/3/95"; +#else +static char rcsid[] = "$OpenBSD: bdisp.c,v 1.4 1998/03/26 21:16:45 pjanzen Exp $"; +#endif #endif /* not lint */ #include "gomoku.h" #include <curses.h> #include <string.h> +#include <err.h> #define SCRNH 24 /* assume 24 lines for the moment */ #define SCRNW 80 /* assume 80 chars for the moment */ @@ -56,8 +61,20 @@ void cursinit() { initscr(); + if ((LINES < SCRNH) || (COLS < SCRNW)) { + endwin(); + errx(1,"Screen too small (need %dx%d)",SCRNW,SCRNH); + } +#ifdef KEY_MIN + keypad(stdscr, TRUE); +#endif /* KEY_MIN */ + nonl(); noecho(); cbreak(); + +#ifdef NCURSES_MOUSE_VERSION + mousemask(BUTTON1_CLICKED, (mmask_t *)NULL); +#endif /* NCURSES_MOUSE_VERSION*/ } /* @@ -66,9 +83,10 @@ cursinit() void cursfini() { - move(23, 0); + move(BSZ4, 0); clrtoeol(); refresh(); + echo(); endwin(); } @@ -116,12 +134,12 @@ bdwho(update) move(21, 0); clrtoeol(); - i = 6 - strlen(plyr[BLACK]) / 2; + i = 4 - strlen(plyr[BLACK]) / 2; move(21, i > 0 ? i : 0); - printw("BLACK/%s", plyr[BLACK]); - i = 30 - strlen(plyr[WHITE]) / 2; - move(21, i); - printw("WHITE/%s", plyr[WHITE]); + printw("BLACK/%s (*)", plyr[BLACK]); + i = 28 - strlen(plyr[WHITE]) / 2; + move(21, i > 24 ? i : 24); + printw("WHITE/%s (O)", plyr[WHITE]); move(21, 19); addstr(" vs. "); if (update) @@ -207,12 +225,12 @@ dislog(str) /* move 'em up */ lastline = 1; } - if (strlen(str) >= SCRNW - 46) - str[SCRNW - 46 - 1] = '\0'; - move(lastline, 46); + if (strlen(str) >= SCRNW - (2 * BSZ4)) + str[SCRNW - (2 * BSZ4) - 1] = '\0'; + move(lastline, (2 * BSZ4)); addstr(str); clrtoeol(); - move(lastline + 1, 46); + move(lastline + 1, (2 * BSZ4)); clrtoeol(); } @@ -225,10 +243,10 @@ ask(str) { int len = strlen(str); - move(23, 0); + move(BSZ4, 0); addstr(str); clrtoeol(); - move(23, len); + move(BSZ4, len); refresh(); } @@ -278,3 +296,135 @@ getline(buf, size) *cp = '\0'; return(c != EOF); } + + +/* Decent (n)curses interface for the game, based on Eric S. Raymond's + * modifications to the battleship (bs) user interface. + */ +int getcoord(void) +{ + static int curx = BSZ / 2; + static int cury = BSZ / 2; + int ny, nx, c; + + BGOTO(cury,curx); + refresh(); + nx = curx; ny = cury; + for (;;) { + mvprintw(BSZ3, (BSZ -6)/2, "(%c %d)", + 'A'+ ((curx > 7) ? (curx+1) : curx), cury + 1); + BGOTO(cury, curx); + + switch(c = getch()) { + case 'k': case '8': +#ifdef KEY_MIN + case KEY_UP: +#endif /* KEY_MIN */ + ny = cury + 1; nx = curx; + break; + case 'j': case '2': +#ifdef KEY_MIN + case KEY_DOWN: +#endif /* KEY_MIN */ + ny = BSZ + cury - 1; nx = curx; + break; + case 'h': case '4': +#ifdef KEY_MIN + case KEY_LEFT: +#endif /* KEY_MIN */ + ny = cury; nx = BSZ + curx - 1; + break; + case 'l': case '6': +#ifdef KEY_MIN + case KEY_RIGHT: +#endif /* KEY_MIN */ + ny = cury; nx = curx + 1; + break; + case 'y': case '7': +#ifdef KEY_MIN + case KEY_A1: +#endif /* KEY_MIN */ + ny = cury + 1; nx = BSZ + curx - 1; + break; + case 'b': case '1': +#ifdef KEY_MIN + case KEY_C1: +#endif /* KEY_MIN */ + ny = BSZ + cury - 1; nx = BSZ + curx - 1; + break; + case 'u': case '9': +#ifdef KEY_MIN + case KEY_A3: +#endif /* KEY_MIN */ + ny = cury + 1; nx = curx + 1; + break; + case 'n': case '3': +#ifdef KEY_MIN + case KEY_C3: +#endif /* KEY_MIN */ + ny = BSZ + cury - 1; nx = curx + 1; + break; + case 'K': + ny = cury + 5; nx = curx; + break; + case 'J': + ny = BSZ + cury - 5; nx = curx; + break; + case 'H': + ny = cury; nx = BSZ + curx - 5; + break; + case 'L': + ny = cury; nx = curx + 5; + break; + case 'Y': + ny = cury + 5; nx = BSZ + curx - 5; + break; + case 'B': + ny = BSZ + cury - 5; nx = BSZ + curx - 5; + break; + case 'U': + ny = cury + 5; nx = curx + 5; + break; + case 'N': + ny = BSZ + cury - 5; nx = curx + 5; + break; + case FF: + nx = curx; ny = cury; + (void)clearok(stdscr, TRUE); + (void)refresh(); + break; +#ifdef NCURSES_MOUSE_VERSION + case KEY_MOUSE: + { + MEVENT myevent; + + getmouse(&myevent); + if (myevent.y >= 1 && myevent.y <= BSZ1 + && myevent.x >= 3 && myevent.x <= (2 * BSZ + 1)) + { + curx = (myevent.x - 3) / 2; + cury = BSZ - myevent.y; + return(PT(curx,cury)); + } + else + beep(); + } + break; +#endif /* NCURSES_MOUSE_VERSION */ + case 'Q': + return(RESIGN); + break; + case 'S': + return(SAVE); + break; + case ' ': + case '\015': /* return */ + (void) mvaddstr(BSZ3, (BSZ -6)/2, " "); + return(PT(curx+1,cury+1)); + break; + } + + curx = nx % BSZ; + cury = ny % BSZ; + } +} diff --git a/games/gomoku/gomoku.6 b/games/gomoku/gomoku.6 index 2f39ab9e572..1f4069e4b82 100644 --- a/games/gomoku/gomoku.6 +++ b/games/gomoku/gomoku.6 @@ -1,4 +1,4 @@ -.\" $OpenBSD: gomoku.6,v 1.1 1996/12/16 06:56:08 downsj Exp $ +.\" $OpenBSD: gomoku.6,v 1.2 1998/03/26 21:16:46 pjanzen Exp $ .\" .\" Copyright (c) 1994 .\" The Regents of the University of California. All rights reserved. @@ -49,16 +49,24 @@ .Op Ar inputfile .Sh DESCRIPTION .Nm Gomoku -is a two player game were the object is to get 5 in a row horizontally, +is a two player game where the object is to get 5 in a row horizontally, vertically or diagonally on a 19 by 19 grid. By convention, black always moves first. With no arguments, .Nm gomoku will display a playing board and prompt for moves from the user. -Valid moves are a letter for the column and a number for the row of an empty -board location. Entering ``quit" or ``resign" will end the game. -You can save the current state of the game by entering ``save" and -supplying a file name when prompted. +The interface is visual and straightforward; you move to a spot +using the rogue(6) / hack(6) motion keys +.Em hjklyubn +and select it with either +.Sq space +or +.Sq return . +The game will beep if you select a location that is already occupied. +To save the game, type +.Sq S +and to quit, type +.Sq Q . The optional file .Ar inputfile can be used to restore a saved game. @@ -74,7 +82,7 @@ has the first move or not respectively. This option was intended for game tournaments where a referee program handles the board display and pits one program against another. .It Fl c -Computer verses computer. +Computer versus computer. .Nm Gomoku will play a game against itself. This is mostly used for testing. .It Fl d @@ -85,10 +93,15 @@ Print the debug information to .Ar debugfile instead of to the standard output. .It Fl u -User verses user. This is mostly used for testing. +User versus user. This is mostly used for testing. +.Sh BUGS +The program is far too slow and uses far too much memory for the quality of +game it provides. .Sh AUTHOR Ralph Campbell .Sh ACKNOWLEDGEMENTS The board display routines were based on the .Nm goref program written by Peter Langston. +The user interface was based on Eric S. Raymond's interface to +.Nm bs . diff --git a/games/gomoku/gomoku.h b/games/gomoku/gomoku.h index 0ff22fac4cd..64310479117 100644 --- a/games/gomoku/gomoku.h +++ b/games/gomoku/gomoku.h @@ -1,4 +1,4 @@ -/* $OpenBSD: gomoku.h,v 1.3 1997/01/26 08:00:52 downsj Exp $ */ +/* $OpenBSD: gomoku.h,v 1.4 1998/03/26 21:16:47 pjanzen Exp $ */ /* * Copyright (c) 1994 * The Regents of the University of California. All rights reserved. @@ -44,9 +44,15 @@ #define BSZ 19 #define BSZ1 (BSZ+1) #define BSZ2 (BSZ+2) +#define BSZ3 (BSZ+3) +#define BSZ4 (BSZ+4) #define BAREA (BSZ2*BSZ1+1) -/* frame dimentions (based on 5 in a row) */ +/* interactive curses stuff */ +#define FF '\014' /* used as redraw command */ +#define BGOTO(y,x) move(BSZ - (y), 2 * (x) + 3) + +/* frame dimensions (based on 5 in a row) */ #define FSZ1 BSZ #define FSZ2 (BSZ-4) #define FAREA (FSZ1*FSZ2 + FSZ2*FSZ2 + FSZ1*FSZ2 + FSZ2*FSZ2) @@ -261,54 +267,55 @@ extern int movelog[BSZ * BSZ]; /* history of moves */ extern int movenum; extern int debug; -extern void addframes __P((int)); -extern void appendcombo __P((struct combostr *)); -extern void ask __P((char *)); -extern void bdinit __P((struct spotstr *)); -extern void bdisp __P((void)); -extern void bdisp_init __P((void)); +void addframes __P((int)); +void appendcombo __P((struct combostr *)); +void ask __P((char *)); +void bdinit __P((struct spotstr *)); +void bdisp __P((void)); +void bdisp_init __P((void)); #ifdef DEBUG -extern void bdump __P((FILE *)); +void bdump __P((FILE *)); #endif -extern void bdwho __P((int)); -extern int better __P((struct spotstr *, struct spotstr *, int)); -extern int checkframes __P((struct combostr *, struct combostr *, +void bdwho __P((int)); +int better __P((struct spotstr *, struct spotstr *, int)); +int checkframes __P((struct combostr *, struct combostr *, struct spotstr *, int, struct ovlp_info *)); #ifdef DEBUG -extern void clearcombo __P((struct combostr *, int)); +void clearcombo __P((struct combostr *, int)); #endif -extern int ctos __P((char *)); -extern void cursfini __P((void)); -extern void cursinit __P((void)); -extern void dislog __P((char *)); -extern void dlog __P((char *)); -extern int getline __P((char *, int)); -extern void init_overlap __P((void)); +int ctos __P((char *)); +void cursfini __P((void)); +void cursinit __P((void)); +void dislog __P((char *)); +void dlog __P((char *)); +int getcoord __P((void)); +int getline __P((char *, int)); +void init_overlap __P((void)); #ifdef DEBUG -extern int list_eq __P((struct combostr **, struct combostr **, int)); +int list_eq __P((struct combostr **, struct combostr **, int)); #endif -extern void log __P((char *)); -extern int lton __P((int)); -extern void makecombo __P((struct combostr *, struct spotstr *, int, int)); -extern void makecombo2 __P((struct combostr *, struct spotstr *, int, int)); -extern void makeempty __P((struct combostr *)); -extern int makemove __P((int, int)); +void log __P((char *)); +int lton __P((int)); +void makecombo __P((struct combostr *, struct spotstr *, int, int)); +void makecombo2 __P((struct combostr *, struct spotstr *, int, int)); +void makeempty __P((struct combostr *)); +int makemove __P((int, int)); #ifdef DEBUG -extern void markcombo __P((struct combostr *)); +void markcombo __P((struct combostr *)); #endif -extern void panic __P((char *)); -extern int pickmove __P((int)); -extern void printcombo __P((struct combostr *, char *)); -extern void qlog __P((char *)); -extern void quit __P((int)); -extern int readinput __P((FILE *)); -extern void scanframes __P((int)); -extern int sortcombo __P((struct combostr **, struct combostr **, struct combostr *)); -extern char *stoc __P((int)); -extern void updatecombo __P((struct combostr *, int)); -extern void update_overlap __P((struct spotstr *)); +void panic __P((char *)); +int pickmove __P((int)); +void printcombo __P((struct combostr *, char *)); +void qlog __P((char *)); +void quit __P((int)); +int readinput __P((FILE *)); +void scanframes __P((int)); +int sortcombo __P((struct combostr **, struct combostr **, struct combostr *)); +char *stoc __P((int)); +void updatecombo __P((struct combostr *, int)); +void update_overlap __P((struct spotstr *)); #ifdef DEBUG -extern void whatsup __P((int)); +void whatsup __P((int)); #endif #define ASSERT(x) diff --git a/games/gomoku/main.c b/games/gomoku/main.c index c75dbd6b20f..6af6bd773e0 100644 --- a/games/gomoku/main.c +++ b/games/gomoku/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.7 1997/01/26 08:00:53 downsj Exp $ */ +/* $OpenBSD: main.c,v 1.8 1998/03/26 21:16:49 pjanzen Exp $ */ /* * Copyright (c) 1994 * The Regents of the University of California. All rights reserved. @@ -42,7 +42,11 @@ static char copyright[] = #endif /* not lint */ #ifndef lint +#if 0 static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 5/4/95"; +#else +static char rcsid[] = "$OpenBSD: main.c,v 1.8 1998/03/26 21:16:49 pjanzen Exp $"; +#endif #endif /* not lint */ #include "gomoku.h" @@ -76,6 +80,8 @@ int movelog[BSZ * BSZ]; /* log of all the moves */ int movenum; /* current move number */ char *plyr[2]; /* who's who */ +static char you[9] = "you\0\0\0\0\0\0"; /* username */ + int main(argc, argv) int argc; @@ -88,6 +94,7 @@ main(argc, argv) "%3d %-6s", "%3d %-6s" }; + char *tmpname; /* revoke privs */ setegid(getgid()); @@ -99,7 +106,10 @@ main(argc, argv) else prog = argv[0]; - while ((ch = getopt(argc, argv, "bcdD:u")) != -1) { + if ((tmpname = getlogin()) != 0) + strncpy(you,tmpname,8); + + while ((ch = getopt(argc, argv, "bcdD:hu")) != -1) { switch (ch) { case 'b': /* background */ interactive = 0; @@ -117,6 +127,19 @@ main(argc, argv) case 'c': /* testing: computer verses computer */ test = 2; break; + case 'h': + default: + fprintf(stderr,"usage: %s [-bcdu] [-D debugfile] [inputfile]\n", + prog); + fprintf(stderr,"\tWhere the options are:\n\t-b : background\n"); + fprintf(stderr,"\t-c : computer vs itself\n"); + fprintf(stderr,"\t-d : print debugging information\n"); + fprintf(stderr,"\t-u : user vs user\n"); + fprintf(stderr, + "\t-D : print debugging information to debugfile\n"); + fprintf(stderr, + "\t The game will be restored from inputfile if one is specified.\n"); + exit(1); } } argc -= optind; @@ -147,21 +170,18 @@ again: #endif if (inputfp == NULL && test == 0) { - for (;;) { - ask("black or white? "); - getline(buf, sizeof(buf)); - if (buf[0] == 'b' || buf[0] == 'B') { - color = BLACK; - break; - } - if (buf[0] == 'w' || buf[0] == 'W') { - color = WHITE; - break; - } - move(22, 0); + ask("black or white? "); + while (((ch = getchar()) != 'b') && (ch != 'B') && + (ch != 'w') && (ch != 'W')) { + move(BSZ3, 0); printw("Black moves first. Please enter `black' or `white'\n"); + refresh(); } - move(22, 0); + if (ch == 'b' || ch == 'B') + color = BLACK; + else + color = WHITE; + move(BSZ3, 0); clrtoeol(); } } else { @@ -201,8 +221,8 @@ again: } } if (interactive) { - plyr[BLACK] = input[BLACK] == USER ? "you" : prog; - plyr[WHITE] = input[WHITE] == USER ? "you" : prog; + plyr[BLACK] = input[BLACK] == USER ? you : prog; + plyr[WHITE] = input[WHITE] == USER ? you : prog; bdwho(1); } @@ -214,17 +234,17 @@ 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; @@ -236,16 +256,9 @@ again: 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("Enter move (hjklyubn/S/Q)"); + curmove = getcoord(); if (curmove == SAVE) { FILE *fp; @@ -263,13 +276,24 @@ again: } if (curmove != RESIGN && board[curmove].s_occ != EMPTY) { - log("Illegal move"); + /* log("Illegal move"); */ + beep(); goto getinput; } + } else { + if (!getline(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; } @@ -283,13 +307,16 @@ again: bdisp(); } if (interactive) { - move(22, 0); + move(BSZ3, 0); switch (i) { case WIN: if (input[color] == PROGRAM) addstr("Ha ha, I won"); else - addstr("Rats! you won"); + 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"); diff --git a/games/gomoku/makemove.c b/games/gomoku/makemove.c index 55781d69c04..6956ddedf47 100644 --- a/games/gomoku/makemove.c +++ b/games/gomoku/makemove.c @@ -1,4 +1,4 @@ -/* $OpenBSD: makemove.c,v 1.3 1997/04/09 02:02:06 deraadt Exp $ */ +/* $OpenBSD: makemove.c,v 1.4 1998/03/26 21:16:50 pjanzen Exp $ */ /* * Copyright (c) 1994 * The Regents of the University of California. All rights reserved. @@ -36,7 +36,11 @@ */ #ifndef lint +#if 0 static char sccsid[] = "@(#)makemove.c 8.2 (Berkeley) 5/3/95"; +#else +static char rcsid[] = "$OpenBSD: makemove.c,v 1.4 1998/03/26 21:16:50 pjanzen Exp $"; +#endif #endif /* not lint */ #include "gomoku.h" diff --git a/games/gomoku/pickmove.c b/games/gomoku/pickmove.c index 2d955ec7011..1b852304a59 100644 --- a/games/gomoku/pickmove.c +++ b/games/gomoku/pickmove.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pickmove.c,v 1.4 1997/01/26 08:00:54 downsj Exp $ */ +/* $OpenBSD: pickmove.c,v 1.5 1998/03/26 21:16:51 pjanzen Exp $ */ /* * Copyright (c) 1994 * The Regents of the University of California. All rights reserved. @@ -36,7 +36,11 @@ */ #ifndef lint +#if 0 static char sccsid[] = "@(#)pickmove.c 8.2 (Berkeley) 5/3/95"; +#else +static char rcsid[] = "$OpenBSD: pickmove.c,v 1.5 1998/03/26 21:16:51 pjanzen Exp $"; +#endif #endif /* not lint */ #include "gomoku.h" diff --git a/games/gomoku/stoc.c b/games/gomoku/stoc.c index 69b1edcd0fe..86cc44e48e7 100644 --- a/games/gomoku/stoc.c +++ b/games/gomoku/stoc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: stoc.c,v 1.2 1996/12/21 21:17:53 tholo Exp $ */ +/* $OpenBSD: stoc.c,v 1.3 1998/03/26 21:16:52 pjanzen Exp $ */ /* * Copyright (c) 1994 * The Regents of the University of California. All rights reserved. @@ -36,7 +36,11 @@ */ #ifndef lint +#if 0 static char sccsid[] = "@(#)stoc.c 8.1 (Berkeley) 7/24/94"; +#else +static char rcsid[] = "$OpenBSD: stoc.c,v 1.3 1998/03/26 21:16:52 pjanzen Exp $"; +#endif #endif /* not lint */ #include "gomoku.h" |