Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.2 9/18/84 / QGSI 2.0; site qubix.UUCP
Path: utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxt!houxm!mtuxo!mtunh!mtung!mtunf!ariel!vax135!petsd!pesnta!hplabs!intelca!t12tst!qubix!lab
From: l...@qubix.UUCP (Larry Bickford)
Newsgroups: net.games
Subject: Battleship (version 1) update
Message-ID: <1626@qubix.UUCP>
Date: Thu, 4-Jul-85 18:08:10 EDT
Article-I.D.: qubix.1626
Posted: Thu Jul 4 18:08:10 1985
Date-Received: Sun, 7-Jul-85 05:57:12 EDT
Distribution: net
Organization: Quadratix ... Quartix
Lines: 725
/* battleships by Judah S. Kaminetsky */
/* Vax 4.2bsd improvements by Tom Truscott (rti-sel!trt) */
/* Improvements on Version 1 by Larry Bickford (qubix!lab):
/* register efficiency
* horizontal expansion (more readable)
* catching SIGINT gracefully
* exit(0) rather than exit(1)
* 4.2bsd correction in flash()
* other various fixes
* Known bug: when battleship exits, your cursor is left at some
* screwball place on the screen. Un-nice.
* Note: Judah has introduced Version 2, which could still use some of
* the above changes, even on SysV. Someone should blend the two.
*/
/* qubix!lab: next line is for 4.2 compilation */
/* cc -O -o bs bs.c -lcurses -ltermcap */
#define MAX_X 12
#define MAX_Y 12
#define NO 1
#define YES 0
#include <curses.h>
/* rti-sel!trt: hack to support old-fashioned curses */
#ifndef A_REVERSE
#define wattron(w, foo) wstandout(w)
#define wattroff(w, foo) wstandend(w)
#endif
long r;/* for random number generator*/
int myscore = 0;
int hisscore = 0;
int hismoves = 1;
int mymoves = 1;
int nextx, nexty;/* next square to attack if adjacent to previous hit*/
int lastx, lasty; /* last move made */
/* qubix!lab: SIGINT catcher */
getout()
{
endwin();
exit(0);
}
main()
{
register WINDOW *mywin, /*player's screen*/
*myscrwin, /*players's score window*/
*hisscrwin, /*computers's score window*/
*hidwin, /* computers hidden screen */
*showwin, /*computer's displayed screen*/
*recwin; /*computers record of my screen */
register int t;
time(&r);/*Seed the random number generator*/
srand((int)(r&0177777L));
initscr();
nonl();
noecho();
cbreak();
signal(2, getout);
err("Battleships System Test - comments to hounx!juda");
mywin = newwin(MAX_Y, MAX_X << 1, 5, 15);
recwin = newwin(MAX_Y, MAX_X, 5, 0);
werase(mywin);
werase(recwin);
wattron(mywin,A_REVERSE);
label_x(mywin);
wrefresh(mywin);
label_y(mywin);
wrefresh(mywin);
wattroff(mywin,A_REVERSE);
/* qubix!lab: deemed unnecessary; need for labels later removed
wattron(recwin,A_REVERSE);
label_x(recwin);
label_y(recwin);
wattroff(recwin,A_REVERSE);
*/
set(mywin,'A',5);
wrefresh(mywin);
set(mywin,'B',4);
wrefresh(mywin);
set(mywin,'S',3);
wrefresh(mywin);
set(mywin,'D',3);
wrefresh(mywin);
set(mywin,'P',2);
wrefresh(mywin);
clrtop();
hidwin = newwin(MAX_Y, MAX_X, 5, 40);
showwin = newwin(MAX_Y, MAX_X << 1, 5, 55);
myscrwin = newwin(4, MAX_X+13, 17, 55);
hisscrwin = newwin(4, MAX_X+13, 17, 15);
werase(hidwin);
werase(showwin);
/** qubix!lab: deemed unnecessary; need for labels later removed **
wattron(hidwin,A_REVERSE);
label_x(hidwin);
wrefresh(hidwin);
label_y(hidwin);
wrefresh(hidwin);
wattroff(hidwin,A_REVERSE);
/**/
wattron(showwin,A_REVERSE);
label_x(showwin);
label_y(showwin);
wrefresh(showwin);
wattroff(showwin,A_REVERSE);
setup(hidwin,'A',5);
setup(hidwin,'B',4);
setup(hidwin,'S',3);
setup(hidwin,'D',3);
setup(hidwin,'P',2);
clrtop();
for(t = (MAX_X-2)*(MAX_Y-2); --t >= 0; )
{
myttack(hidwin,showwin);
myrecord(myscrwin);
if(myscore>16)
{
msg("YOU WIN!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
wrefresh(hidwin);
wrefresh(recwin);
endwin();
exit(0);
}
hisattack(mywin,recwin);
hisrecord(hisscrwin);
if(hisscore>16)
{
msg("YOU LOSE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
wrefresh(hidwin);
wrefresh(recwin);
endwin();
exit(0);
}
}
endwin();
}
/*************************************************************/
/* Draw x axis labels */
label_x(win)
register WINDOW *win;
{
register int x,y;
register int ch;
for(y=0;y<MAX_Y;y+=MAX_Y-1)
{
for(x=1,ch=0;x<MAX_X-1;x++,ch++)
{
/* qubix!lab: horiz. expand */
wmove(win,y,x << 1);
waddch(win,ch+'0');
}
}
touchwin(win);
}
/*****************************************************************/
/* Draw y axis labels */
label_y(win)
register WINDOW *win;
{
register int x,y;
/* in columns 1 and MAX_X */
for(x=0;x<MAX_X;x+=MAX_X-1)
{
for(y=0;y<MAX_Y;y++)
{
/* qubix!lab: horiz. expand */
wmove(win,y,x << 1);
waddch(win,y+'/');/*start with char 0*/
}
}
touchwin(win);
}
/************************************************************************/
/* Place ship of length len, represented by character ch at coordinates
* y, x */
/* direction up, down, right, left from start */
place(win,len,ch,init_y,init_x,dir)
register WINDOW *win;
register int len; /*length*/
char ch;
register int init_y,init_x;
register int dir; /*direction*/
{
register int i;
char c;
register int dir_y, dir_x;
register int x, y;
dir_x=xdir(dir);
dir_y=ydir(dir);
/* avoid collisions with existing characters*/
for(i=0, x=init_x, y=init_y; i<len; i++, x=x+dir_x, y=y+dir_y)
{
if(x < 1 || y < 1 || y >= MAX_Y-1) return(1);
if(dir > 0) if(x >= MAX_X - 1) return(1);
/* qubix!lab: horiz expand */
else if(x >= (MAX_X-1)<<1) return(1);
wmove(win,y,x);
c=winch(win);
if(c!=' ')
{
return(1);
}
}
/* place characters if no collision */
for(i=0, x=init_x, y=init_y; i<len; i++, x=x+dir_x, y=y+dir_y)
{
wmove(win,y,x);
waddch(win,ch);
}
return(0);
}
/*********************************************************************/
/* Determine x direction increment or decrement */
/* neg values are input by user => expand to 2X */
xdir(dir)
register int dir;
{
register int xdir;
switch(dir){
case 0 :/*up*/
xdir=0;
break;
case 1 :/*down*/
case -1 :/*down*/
xdir=0;
break;
case 2 :/*right*/
xdir=1;
break;
case -2 :/*right*/
xdir=2;
break;
case 3 :/*left*/
xdir=(-1);
break;
case -3 :/*left*/
xdir=(-2);
break;
default:
xdir=1;
break;
}
return(xdir);
}
/*********************************************************************/
/* Determine y direction increment or decrement */
ydir(dir)
register int dir;
{
register int ydir;
switch(dir){
case 0 :/*up*/
ydir=(-1);
break;
case -1:
case 1 :/*down*/
ydir=1;
break;
case -2:
case 2 :/*right*/
ydir=0;
break;
case -3:
case 3 :/*left*/
ydir=0;
break;
default:
ydir=0;
break;
}
return(ydir);
}
/***********************************************************************/
/* generate random number between 0 and high (arg1), retrun random number */
random(high)
register int high;
{
/* qubix!lab: without right-shift, and high = 10, was returning
* values ending alternately 00 or 10 (binary). Un-random.
*/
return( ((rand() >> 2) % high) +1);
}
/********************************************************************/
/* place ship for computer*/
setup(win,ship,length)
register WINDOW *win;
char ship;
register int length;
{
register int y , x;
register int dir;
for(;;)
{
msg("The computer is now placing its ships in a random manner");
x=random(MAX_X-2);
y=random(MAX_X-2);
dir=random(3);
if(place(win,length,ship,y,x,dir)!=1)
{
return(0);
}
}
}
/********************************************************************/
/* get x coordinate from user*/
get_x()
{
register WINDOW *xwin;
register int i, c;
char ch;
xwin = newwin(1, COLS, 1, 0);/*line 1*/
werase(xwin);
wprintw(xwin,"Enter x (horizontal) coordinate [0-9] (q to exit):\t");
touchwin(stdscr);
wrefresh(xwin);
c=getch();
out(c);
waddch(xwin,c);
touchwin(stdscr);
wrefresh(xwin);
return(c-'0'+1);
}
/********************************************************************/
/* get y coordinate from user*/
get_y()
{
register WINDOW *ywin;
register int i, c;
char ch;
ywin = newwin(1, COLS, 2, 0);/*line 2*/
werase(ywin);
wprintw(ywin,"Enter y (vertical) coordinate [0-9] (q to exit):\t");
touchwin(stdscr);
wrefresh(ywin);
c=getch();
out(c);
waddch(ywin,c);
touchwin(stdscr);
wrefresh(ywin);
return(c-'0'+1);
}
/*********************************************************************/
/* get dir from user*/
get_dir()
{
register WINDOW *dirwin;
register int i, c;
char ch;
dirwin = newwin(1, COLS, 3, 0);/*line 3*/
werase(dirwin);
wprintw(dirwin,
"Enter Direction, 0 is up, 1 is down, 2 is right, 3 is left: (q to exit)");
touchwin(stdscr);
wrefresh(dirwin);
c=getch();
out(c);
waddch(dirwin,c);
touchwin(stdscr);
wrefresh(dirwin);
/* get the NEGATIVE value */
return(c-'0');
}
/*********************************************************************/
/* place ship for player*/
set(win,ship,length)
register WINDOW *win;
char ship;
register int length;
{
register int y , x;
register int dir;
char msg_str[80];
for(;;)
{
sprintf(msg_str,
"PLACE SHIP %c, length %d avoiding collisions",ship,length);
msg(msg_str);
if(verify(x = get_x(), 0, MAX_X-2)==1)
{
continue;
}
if(verify(y = get_y(), 0, MAX_Y-2)==1)
{
continue;
}
if(verify( dir = get_dir(), 0, 3) == 1)
{
continue;
}
/* qubix!lab: horiz expand; also note negative */
if(place(win, length, ship, y, x<<1, -dir) != 1)
{
touchwin(win);
return(0);
}
}
}
/***********************************************************************/
msg(str)
register char *str;
{
register WINDOW *msgwin;
msgwin = newwin(1, COLS, 0,0);
werase(msgwin);
wattron(msgwin, A_REVERSE);
wprintw(msgwin, "%s", str);
touchwin(stdscr);
wrefresh(msgwin);
return(0);
}
/***********************************************************************/
verify(c,low,high)
register int c;
register int low;
register int high;
{
char msgstr[80];
if(c < low || c > high)
{
sprintf(msgstr,"%c is out of legal range %c to %c",c,low,high);
return(1);
}
else
{
return(0);
}
}
/*********************************************************************/
/*player attack computer - goes to attack coordinates on hidwin*/
/*and copies ch (+attributes?) to showwin - touchwin and refresh showwin*/
/* allows duplicate moves but does not score duplicaate hits*/
myttack(hidwin,showwin)
register WINDOW *hidwin,
*showwin;
{
register int y , x;
register int hit;
char c;
char d;
char msg_str[80];
msg("ATTACK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
while(verify(x=get_x(),0,MAX_X-2)==1)
{
}
while(verify(y=get_y(),0,MAX_Y-2)==1)
{
}
wmove(hidwin,y,x);
c=winch(hidwin);
if(c!=' ' && c != '.')
{
hit=YES;
}
wmove(showwin,y,x << 1);
d=winch(showwin);
if(hit == YES && (d==' ' || d=='.')) /* first hit - not repeat */
{
flash();
myscore++;
}
wattron(showwin,A_REVERSE);
/* qubix!lab: record where I've been */
if(c == ' ') c = '.';
waddch(showwin,c);
touchwin(showwin);
wrefresh(showwin);
lastx = x;
lasty = y;
}
/***************************************************************************/
/* clear top of screen */
clrtop()
{
register WINDOW *topwin;
register int i, c;
char ch;
topwin = newwin(5, COLS, 0, 0);/*top 5 lines*/
werase(topwin);
touchwin(topwin);
wrefresh(topwin);
}
/*********************************************************************/
/*computer attack player - goes to attack coordinates on recwin*/
/* checks recwin - blank means haven't attacked here yet */
/* if so go to coord on mywin - attack & record result on recwin */
hisattack(mywin,recwin)
register WINDOW *mywin;
register WINDOW *recwin;
{
register int y , x;
char c;
char mark='+';
clrtop();
for(;;)
{
if(nextshot(recwin)==YES)
{
x=nextx;
y=nexty;
}
else /* if(nextshot(recwin)==NO) */
{
x=random(MAX_X-2);
y=random(MAX_Y-2);
}
lastx = x;
lasty = y;
wmove(recwin,y,x);/*check for repeat move*/
c=winch(recwin);
if(c!=' ')/*repeat move */
{
continue;
}
else
{
/* qubix!lab: horiz expand */
wmove(mywin,y,x << 1);
c=winch(mywin);
if(c!=' ')/*hit*/
{
flash();
mark=c;/*mark recwin with ship character*/
hisscore++;
}
else c = '.';
wattron(mywin,A_REVERSE);
waddch(mywin,c);
touchwin(mywin);
wrefresh(mywin);
waddch(recwin,mark);
/*mark square as tried already and result + for blank or char for ship */
touchwin(recwin);
return(YES);
}
}
return(NO);
}
/***********************************************************************/
err(str)
register char *str;
{
register WINDOW *errwin;
/* rti-sel!trt: fix for window manager */
errwin=newwin(1,COLS,LINES-1,0);
if (errwin == NULL) {
fprintf(stderr, "cannot create error window\n");
return;
}
werase(errwin);
wattron(errwin,A_REVERSE);
wprintw(errwin,"%s",str);
touchwin(stdscr);
wrefresh(errwin);
return(0);
}
/***********************************************************************/
out(c)
char c;
{
if(c=='q')
{
endwin();
exit(1);
}
}
/*********************************************************************/
myrecord(win)
register WINDOW *win;
{
werase(win);
wprintw(win, "Try %d,%d: ",lastx-1,lasty-1);
wprintw(win,"hit %d ",myscore);
wprintw(win,"move %d\n",mymoves++);
touchwin(win);
wrefresh(win);
}
/*********************************************************************/
hisrecord(win)
register WINDOW *win;
{
werase(win);
wprintw(win, "Try %d,%d: ",lastx-1,lasty-1);
wprintw(win,"hit %d ",hisscore);
wprintw(win,"move %d\n",hismoves++);
touchwin(win);
wrefresh(win);
}
/************************************************************************/
/* check win for previous hit and choose next guess at adjacent square */
nextshot(win)
register WINDOW *win;
{
register int y;
register int x;
register int ax;
register int by;
char c;
for(by = 1; by < MAX_Y-1; by++)
{
for(ax = 1;ax < MAX_X-1; ax++)
{
wmove(win,by,ax);
c=winch(win);
if(c!=' '&&c!='+')
/* space was hit previously */
{
/* eliminate need for hidden labels */
y=by;
/*right*/
if((x=ax+1) < MAX_X-1 &&
check(win,y,x)==YES )
{
return(YES);
}
/*left*/
if((x=ax-1) > 0 &&
check(win,y,x)==YES )
{
return(YES);
}
x=ax;
/*1 square down */
if((y=by+1) < MAX_Y - 1 &&
check(win,y,x)==YES )
{
return(YES);
}
x=ax;
/*up*/
if((y=by-1) > 0 &&
check(win,y,x)==YES )
{
return(YES);
}
}
}
}
return(NO);/* no untried squares adjacent to hits */
}
/*******************************************************************/
/* check y,x on win, return YES if blank - not shot at yet
return NO if not blank */
check(win,y,x)
register WINDOW *win;
register int y;
register int x;
{
char c;
wmove(win,y,x);
c=winch(win);
if(c==' ')
/* adjacent to previous hit & blank */
{
nextx=x;
nexty=y;
return(YES);
}
else
{
return(NO);
}
}
#ifndef A_REVERSE
/* need to define some other routines */
cbreak()
{
crmode();
}
flash()
{
extern int _putchar();
/* qubix!lab: no ';' because of ways curses.h defines it! */
if (VB)
_puts(VB)
else
putchar('\07');
}
#endif
--
The Ice Floe of Larry Bickford
{amd,decwrl,sun,idi,ittvax}!qubix!lab
You can't settle the issue until you've settled how to settle the issue.
|