+ BS 2.0
+
Battleships is an intrinsically silly game, but I couldn't resist fixing this
sucker. It now has a purely visual interface (you place ships and call for
shots by moving the cursor around the board using the standard yuhjklbn keys).
The code now lints as clean as the broken SysV curses lint library will let it.
Some #ifdefs in the code should result in the right things being done for
-BSD or USG systems. They key off A_UNDERLINE.
+BSD or USG systems. They key off A_UNDERLINE. If you're using the Linux
+ncurses library, tell the makefile.
This was probably a waste of a day or so. But what the hack -- rewriting the
strategy robot as an FSM was fun, and maybe the interface will set a good
O.K., I feel better now that I've got that off my chest...
+November 1993: I've added function key support, and ANSI/POSIXized the code.
+
Eric S. Raymond
- esr@snark.uu.net
+ esr@snark.thyrsus.com
* with improved user interface, autoconfiguration and code cleanup
* 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.
*/
+#define _POSIX_SOURCE
#include <stdio.h>
+#include <termios.h>
#include <curses.h>
#include <signal.h>
#include <ctype.h>
extern long time();
extern void exit();
+static bool checkplace();
+
/*
* Constants for tuning the random-fire algorithm. It prefers moves that
* diagonal-stripe the board with a stripe separation of srchstep. If
static char ptboat[] = "PT Boat";
static char name[40];
-static char dftname[] = "Stranger";
+static char dftname[] = "stranger";
/* direction constants */
#define E 0
(void)signal(SIGQUIT,uninitgame);
if(tmpname = getlogin())
+ {
(void)strcpy(name,tmpname);
+ name[0] = toupper(name[0]);
+ }
else
(void)strcpy(name,dftname);
- name[0] = toupper(name[0]);
(void)initscr();
+#ifdef KEY_MIN
+ keypad(stdscr, TRUE);
+#endif /* KEY_MIN */
(void)saveterm();
(void)nonl();
(void)cbreak();
ss->hits = 0;
}
+static int rnd(n)
+int n;
+{
+ return(((rand() & 0x7FFF) % n));
+}
+
static void randomplace(b, ss)
/* generate a valid random ship placement into px,py */
int b;
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 */
(void) getch();
}
-static int rnd(n)
-int n;
-{
- return(((rand() & 0x7FFF) % n));
-}
-
static int getcoord(atcpu)
int atcpu;
{
switch(c = getch())
{
- case 'k': case '8': ny = cury+BDEPTH-1; nx = curx; break;
- case 'j': case '2': ny = cury+1; nx = curx; break;
- case 'h': case '4': ny = cury; nx = curx+BWIDTH-1; break;
- case 'l': case '6': ny = cury; nx = curx+1; break;
- case 'y': case '7': ny = cury+BDEPTH-1; nx = curx+BWIDTH-1; break;
- case 'b': case '1': ny = cury+1; nx = curx+BWIDTH-1; break;
- case 'u': case '9': ny = cury+BDEPTH-1; nx = curx+1; break;
- case 'n': case '3': ny = cury+1; nx = curx+1; break;
+ case 'k': case '8':
+#ifdef KEY_MIN
+ case KEY_UP:
+#endif /* KEY_MIN */
+ ny = cury+BDEPTH-1; nx = curx;
+ break;
+ case 'j': case '2':
+#ifdef KEY_MIN
+ case KEY_DOWN:
+#endif /* KEY_MIN */
+ ny = cury+1; nx = curx;
+ break;
+ case 'h': case '4':
+#ifdef KEY_MIN
+ case KEY_LEFT:
+#endif /* KEY_MIN */
+ ny = cury; nx = curx+BWIDTH-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+BDEPTH-1; nx = curx+BWIDTH-1;
+ break;
+ case 'b': case '1':
+#ifdef KEY_MIN
+ case KEY_C1:
+#endif /* KEY_MIN */
+ ny = cury+1; nx = curx+BWIDTH-1;
+ break;
+ case 'u': case '9':
+#ifdef KEY_MIN
+ case KEY_A3:
+#endif /* KEY_MIN */
+ ny = cury+BDEPTH-1; nx = curx+1;
+ break;
+ case 'n': case '3':
+#ifdef KEY_MIN
+ case KEY_C3:
+#endif /* KEY_MIN */
+ ny = cury+1; nx = curx+1;
+ break;
case FF:
nx = curx; ny = cury;
(void)clearok(stdscr, TRUE);
return(collide);
}
-static int checkplace(b, ss, vis)
+static bool checkplace(b, ss, vis)
int b;
ship_t *ss;
int vis;
yend = ss->y + ss->length * yincr[ss->dir];
if (!ONBOARD(xend, yend))
{
- if(vis)
+ if (vis)
switch(rnd(3))
{
case 0:
error("There's already a ship there");
break;
case 1:
- error("Collision alert! Aaaaaagh!");
+ error("Collision alert! Aaaaaagh!");
break;
case 2:
error("Er, Admiral, what about the other ship?");
break;
}
- return(0);
+ return(FALSE);
}
}
- return(1);
+ return(TRUE);
}
static int awinna()
-.TH BATTLESHIPS 6 "Aug 23, 1989"
+.TH BATTLESHIPS 6 "Nov 15 1993"
.SH NAME
bs \- battleships game
.SH SYNOPSIS
This program allows you to play the familiar Battleships game against the
computer on a 10x10 board. The interface is visual and largely
self-explanatory; you place your ships and pick your shots by moving the
-cursor around the `sea' with the rogue/hack motion keys hjklyubn.
+cursor around the `sea' with the rogue/hack motion keys hjklyubn. If
+your UNIX has a modern (non-BSD) curses, your arrow keys will also work.
.PP
Note that when selecting a ship to place, you must type the capital letter
(these are, after all, capital ships). During ship placement, the `r' command
-c option disables this check and allows them to close-pack.
.PP
The algorithm the computer uses once it has found a ship to sink is provably
-optimal. The dispersion criterion for the random-fire algorithm may not be.
+optimal. The dispersion criterion for the random-fire algorithm may not be.
.SH AUTHORS
Originally written by one Bruce Holloway in 1986. Salvo mode added by Chuck A.
DeGaul (cbosgd!cad). Visual user interface, `closepack' option, code rewrite
-and manual page by Eric S. Raymond <esr@snark.thyrsus.com> August 1989.
+and manual page by Eric S. Raymond <esr@snark.thyrsus.com> August
+1989. Keypad support and ANSI/POSIX conformance, November '93.
+