* by Eric S. Raymond <esr@snark.thyrsus.com>
* v1.2 with color support and minor portability fixes, November 1990
* v2.0 featuring strict ANSI/POSIX conformance, November 1993.
- * v2.1 for Linux, October 1994.
- * Slipstreamed in fixes to make it gcc -Wall clean, May '95.
+ * v2.1 with ncurses mouse support, September 1995
*/
#define _POSIX_SOURCE
#include <unistd.h>
#include <string.h>
#include <assert.h>
+#include <time.h>
#ifndef SIGIOT
#define SIGIOT SIGABRT
#define strchr index
#endif /* !A_UNDERLINE */
-#ifdef isxdigit /* aha, must be an AT&T system... */
-
-#if !defined(__386BSD__) && !defined(__bsdi__)
-#define srand(n) srand48(n)
-#define rand() lrand48()
-extern long lrand48();
-extern void srand48();
-#endif
-
-#define bzero(s, n) (void)memset((char *)(s), '\0', n)
-extern char *memset();
-/*
- * Try this if ungetch() fails to resolve.
- *
- * #define ungetch ungetc
- */
-#endif /* isxdigit */
-
-extern unsigned sleep();
-extern char *strchr(), *strcpy();
-extern long time();
-extern void exit();
-
-static bool checkplace();
+static int getcoord(int);
/*
* Constants for tuning the random-fire algorithm. It prefers moves that
#define CXBASE 48
#define CY(y) (CYBASE + (y))
#define CX(x) (CXBASE + (x)*3)
+#define CYINV(y) ((y) - CYBASE)
+#define CXINV(x) (((x) - CXBASE) / 3)
#define cgoto(y, x) (void)move(CY(y), CX(x))
#define ONBOARD(x, y) (x >= 0 && x < BWIDTH && y >= 0 && y < BDEPTH)
}
ship_t;
+static bool checkplace(int b, ship_t *ss, int vis);
+
ship_t plyship[SHIPTYPES] =
{
{ carrier, 0, 'A', 5},
#define PR (void)addstr
-static void uninitgame(sig)
+static void uninitgame(int sig)
/* end the game, either normally or due to signal */
-int sig;
{
clear();
(void)refresh();
(void)resetterm();
(void)echo();
(void)endwin();
- exit(0);
+ exit(sig);
}
-static void announceopts()
+static void announceopts(void)
/* announce which game options are enabled */
{
if (salvo || blitz || closepack)
"Playing standard game (noblitz, nosalvo, noclosepack)");
}
-static void intro()
+static void intro(void)
{
- extern char *getlogin();
+ extern char *getlogin(void);
char *tmpname;
- srand(time(0L)+getpid()); /* Kick the random number generator */
+ srand((unsigned)(time(0L)+getpid())); /* Kick the random number generator */
(void) signal(SIGINT,uninitgame);
(void) signal(SIGINT,uninitgame);
init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK);
#endif /* A_COLOR */
+#ifdef NCURSES_MOUSE_VERSION
+ (void) mousemask(BUTTON1_CLICKED, (mmask_t *)NULL);
+#endif /* NCURSES_MOUSE_VERSION*/
}
/* VARARGS1 */
-static void prompt(n, f, s)
+static void prompt(int n, char *f, char *s)
/* print a message at the prompt line */
-int n;
-char *f, *s;
{
(void) move(PROMPTLINE + n, 0);
(void) clrtoeol();
(void) refresh();
}
-static void error(s)
-char *s;
+static void error(char *s)
{
(void) move(PROMPTLINE + 2, 0);
(void) clrtoeol();
}
}
-static void placeship(b, ss, vis)
-int b;
-ship_t *ss;
-int vis;
+static void placeship(int b, ship_t *ss, int vis)
{
int l;
ss->hits = 0;
}
-static int rnd(n)
-int n;
+static int rnd(int n)
{
return(((rand() & 0x7FFF) % n));
}
-static void randomplace(b, ss)
+static void randomplace(int b, ship_t *ss)
/* generate a valid random ship placement into px,py */
-int b;
-ship_t *ss;
{
register int bwidth = BWIDTH - ss->length;
register int bdepth = BDEPTH - ss->length;
(!checkplace(b, ss, FALSE));
}
-static void initgame()
+static void initgame(void)
{
int i, j, unplaced;
ship_t *ss;
(void) move(PROMPTLINE + 2, 0);
announceopts();
- bzero(board, sizeof(char) * BWIDTH * BDEPTH * 2);
- bzero(hits, sizeof(char) * BWIDTH * BDEPTH * 2);
+ memset(board, 0, sizeof(char) * BWIDTH * BDEPTH * 2);
+ memset(hits, 0, sizeof(char) * BWIDTH * BDEPTH * 2);
for (i = 0; i < SHIPTYPES; i++)
{
ss = cpuship + i;
(void) mvaddstr(PYBASE - 1, PXBASE - 3,numbers);
for(i=0; i < BDEPTH; ++i)
{
- (void) mvaddch(PYBASE + i, PXBASE - 3, i + 'A');
+ (void) mvaddch(PYBASE + i, PXBASE - 3, (chtype)(i + 'A'));
#ifdef A_COLOR
if (has_colors())
attron(COLOR_PAIR(COLOR_BLUE));
attrset(0);
#endif /* A_COLOR */
(void) addch(' ');
- (void) addch(i + 'A');
+ (void) addch((chtype)(i + 'A'));
}
(void) mvaddstr(PYBASE + BDEPTH, PXBASE - 3,numbers);
(void) mvaddstr(CYBASE - 2, CXBASE + 7,"Hit/Miss Board");
(void) mvaddstr(CYBASE - 1, CXBASE - 3, numbers);
for(i=0; i < BDEPTH; ++i)
{
- (void) mvaddch(CYBASE + i, CXBASE - 3, i + 'A');
+ (void) mvaddch(CYBASE + i, CXBASE - 3, (chtype)(i + 'A'));
#ifdef A_COLOR
if (has_colors())
attron(COLOR_PAIR(COLOR_BLUE));
attrset(0);
#endif /* A_COLOR */
(void) addch(' ');
- (void) addch(i + 'A');
+ (void) addch((chtype)(i + 'A'));
}
(void) mvaddstr(CYBASE + BDEPTH,CXBASE - 3,numbers);
ss = (ship_t *)NULL;
do {
- extern char *strchr();
- static char getcoord();
char c, docked[SHIPTYPES + 2], *cp = docked;
/* figure which ships still wait to be placed */
}
else if (c == 'R')
{
- prompt(1, "Placing the rest of your fleet at random...");
+ prompt(1, "Placing the rest of your fleet at random...", "");
for (ss = plyship; ss < plyship + SHIPTYPES; ss++)
if (!ss->placed)
{
(void) mvprintw(HYBASE+5, HXBASE,
" ");
- (void) prompt(0, "Press any key to start...");
+ (void) prompt(0, "Press any key to start...", "");
(void) getch();
}
-static int getcoord(atcpu)
-int atcpu;
+static int getcoord(int atcpu)
{
int ny, nx, c;
(void)clearok(stdscr, TRUE);
(void)refresh();
break;
+#ifdef NCURSES_MOUSE_VERSION
+ case KEY_MOUSE:
+ {
+ MEVENT myevent;
+
+ getmouse(&myevent);
+ if (atcpu
+ && myevent.y >= CY(0) && myevent.y <= CY(BDEPTH)
+ && myevent.x >= CX(0) && myevent.x <= CX(BDEPTH))
+ {
+ curx = CXINV(myevent.x);
+ cury = CYINV(myevent.y);
+ return(' ');
+ }
+ else
+ beep();
+ }
+ break;
+#endif /* NCURSES_MOUSE_VERSION */
default:
if (atcpu)
(void) mvaddstr(CYBASE + BDEPTH + 1, CXBASE + 11, " ");
}
}
-static int collidecheck(b, y, x)
+static int collidecheck(int b, int y, int x)
/* is this location on the selected zboard adjacent to a ship? */
-int b;
-int y, x;
{
int collide;
return(collide);
}
-static bool checkplace(b, ss, vis)
-int b;
-ship_t *ss;
-int vis;
+static bool checkplace(int b, ship_t *ss, int vis)
{
int l, xend, yend;
return(TRUE);
}
-static int awinna()
+static int awinna(void)
{
int i, j;
ship_t *ss;
return(-1);
}
-static ship_t *hitship(x, y)
+static ship_t *hitship(int x, int y)
/* register a hit on the targeted ship */
-int x, y;
{
ship_t *sb, *ss;
char sym;
for (i = -1; i <= ss->length; ++i)
{
- int x, y;
+ int x1, y1;
- x = bx + i * xincr[ss->dir];
- y = by + i * yincr[ss->dir];
- if (ONBOARD(x, y))
+ x1 = bx + i * xincr[ss->dir];
+ y1 = by + i * yincr[ss->dir];
+ if (ONBOARD(x1, y1))
{
- hits[turn][x][y] = MARK_MISS;
+ hits[turn][x1][y1] = MARK_MISS;
if (turn % 2 == PLAYER)
{
- cgoto(y, x);
+ cgoto(y1, x1);
#ifdef A_COLOR
if (has_colors())
attron(COLOR_PAIR(COLOR_GREEN));
for (i = 0; i < ss->length; ++i)
{
- int x = ss->x + i * xincr[ss->dir];
- int y = ss->y + i * yincr[ss->dir];
+ int x1 = ss->x + i * xincr[ss->dir];
+ int y1 = ss->y + i * yincr[ss->dir];
- hits[turn][x][y] = ss->symbol;
+ hits[turn][x1][y1] = ss->symbol;
if (turn % 2 == PLAYER)
{
- cgoto(y, x);
- (void) addch(ss->symbol);
+ cgoto(y1, x1);
+ (void) addch((chtype)(ss->symbol));
}
}
return((ship_t *)NULL);
}
-static int plyturn()
+static int plyturn(void)
{
ship_t *ss;
bool hit;
char *m = NULL;
- prompt(1, "Where do you want to shoot? ");
+ prompt(1, "Where do you want to shoot? ", "");
for (;;)
{
(void) getcoord(COMPUTER);
if (hits[PLAYER][curx][cury])
{
- prompt(1, "You shelled this spot already! Try again.");
+ prompt(1, "You shelled this spot already! Try again.", "");
beep();
}
else
return(hit);
}
-static int sgetc(s)
-char *s;
+static int sgetc(char *s)
{
char *s1;
int ch;
if (islower(ch))
ch = toupper(ch);
if (ch == CTRLC)
- uninitgame();
+ uninitgame(0);
for (s1=s; *s1 && ch != *s1; ++s1)
continue;
if (*s1)
}
-static void randomfire(px, py)
+static void randomfire(int *px, int *py)
/* random-fire routine -- implements simple diagonal-striping strategy */
-int *px, *py;
{
static int turncount = 0;
static int srchstep = BEGINSTEP;
#define S_HIT 1
#define S_SUNK -1
-static bool cpufire(x, y)
+static bool cpufire(int x, int y)
/* fire away at given location */
-int x, y;
{
bool hit, sunk;
ship_t *ss = NULL;
* unstructuredness below. The five labels are states which need to be held
* between computer turns.
*/
-static bool cputurn()
+static bool cputurn(void)
{
#define POSSIBLE(x, y) (ONBOARD(x, y) && !hits[COMPUTER][x][y])
#define RANDOM_FIRE 0
return(hit);
}
-int playagain()
+static
+int playagain(void)
{
int j;
ship_t *ss;
return(sgetc("YN") == 'Y');
}
-static void do_options(c,op)
-int c;
-char *op[];
+static void do_options(int c, char *op[])
{
register int i;
}
}
-static int scount(who)
-int who;
+static int scount(int who)
{
register int i, shots;
register ship_t *sp;
return(shots);
}
-main(argc, argv)
-int argc;
-char *argv[];
+int main(int argc, char *argv[])
{
do_options(argc, argv);
}
} while
(playagain());
- uninitgame();
+ uninitgame(0);
/*NOTREACHED*/
}