[comp.sources.games] v05i002: wanderer - mini rogue-like adventure game, Part01/02

games@tekred.TEK.COM (07/06/88)

Submitted by: Steven Shipway <maujp@sol.warwick.ac.uk>
Comp.sources.games: Volume 5, Issue 2
Archive-name: wanderer/Part01

	[I've played this and verified that it works. It's kind of fun
	to play when you want something without all the complexity of
	rogue or hack. Its only major requirement is the use of curses.  -br]

[[The game is similar to games like 'Repton' , 'Boulderdash' , and the like,
and comes with a number of screens and instructions on how to easily add new
ones. It also has a hiscore table. Any feedback as to how wonderful/awful/
badly written is is would be appreciated - esp if the message is favourable!
Mail to maujp@sol.warwick.ac.uk.
                                        -Steve Shipway]]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 2)."
# Contents:  README MANIFEST fall.c game.c gamedev.c jump.c mdev.c
#   scores.c screens wand.intro wanderer.6
# Wrapped by billr@saab on Sun Jul  3 21:46:07 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(3381 characters\)
sed "s/^X//" >README <<'END_OF_README'
X                        * W A N D E R E R *
X                ----------------------------------
X
X    This program requires the header files string.h and curses.h, and
Xthe curses and termcap libraries libcurses.a and libtermcap.a. If your
Xsystem doesnt have them then you might as well give up now.
X
X    Still here? Good - then everythings OK.
X
X    First thing to do is edit the wand_head.h file. Most of the filenames
Xare self-explanatory - the lock file is usually in /tmp , you probably
Xdont need to change it. SCREENPATH is the directory in which the screen
Xfiles, screen.* , are kept. HISCOREPATH is the name of the hiscore table
Xfile - this will be created when you run the program, but must have group
Xand other read and write permission.
X    The masterpassword is the password that you can give when you try to
Xjump screen with ~ (see file wand.info) that will allow you to go to any
Xscreen at will. This is for wanderer 'wizards' only. Separate passwords
Xfor each screen are drawn from the file /usr/dict/words - if you dont have
Xit on your system then you'll have to change the file jump.c . These passwords
Xare given to the player upon completing each screen.
X
X    You can create new screens easily - just use the same format as the
Xscreens supplied. Each line of data MUST be the correct length , or nasty
Xthings happen because I didnt bother to put in an intelligent datafile reader
Xfunction. You can test out new screens using the development program included
Xin the package, which allows you to play a screen held in the file ./screen
Xwhich must be in standard Wanderer format. Obviously, no hiscores are saved
Xby this program. All screens must be readable by everyone.
X
X    The hiscore table holds only one score per name - this is to prevent
Xone person from taking over the entire table. If you object to this, then its
Xeasy to stop - just remove a few bits of scores.c. Unfortunately, this bit
Xcontains a *BUG* - if you score enouh to place yourself in the table directly
Xbelow your current hiscore, then both are retained until you next play. It
Xshould be easy to fix this, but I've never got around to it yet. The hiscore
Xsystem is absolutesly *full* of bad, obfuscated programming, and the lack of
Xany real commenting does not help, I'm afraid.
X    There is also a program called 'erase' included, which will allow you to
Xremove entries from the hiscore table. This table must, of course, have group
Xand other read/write permission. 'erase' has a nasty bug in it - to finish an
Xedit, type 0. If you use anything else, its liable to wipe the entire
Xtable...
X
X    Not much more to say, really. Info on playing the game can be found in
Xthe wand.info file. Once you have edited the header file, just type 'make'
Xto run the makefile. You may need to edit the makefile so that it conforms
Xwith your system. If you dont know how to do this, there's bound to be
Xsomeone around who does.
X
X    All that remains is for me to say that the source was written by me,
XSteven Shipway,  on a sun/3-160 called poppy at Warwick University. The
Xlatter are completely unaware of this major breakthrough in software
Xdesign (:-), and this is probably a good idea, since they may well disapprove
Xof this use of computing time and facilities! (Only kidding)
X
X                                -Steven Shipway
X
X------------------------------------------------------------------------------
END_OF_README
if test 3381 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f MANIFEST -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"MANIFEST\"
else
echo shar: Extracting \"MANIFEST\" \(1044 characters\)
sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X MANIFEST                  1	This shipping list
X Makefile                  2	
X README                    1	
X display.c                 2	
X erase.c                   2	
X fall.c                    1	
X game.c                    1	
X gamedev.c                 1	
X icon.c                    2	
X jump.c                    1	
X m.c                       2	
X mdev.c                    1	
X read.c                    2	
X scores.c                  1	
X screens                   1	
X screens/screen.1          2	
X screens/screen.10         2	
X screens/screen.11         2	
X screens/screen.12         2	
X screens/screen.13         2	
X screens/screen.2          2	
X screens/screen.3          2	
X screens/screen.4          2	
X screens/screen.5          2	
X screens/screen.6          2	
X screens/screen.7          2	
X screens/screen.8          2	
X screens/screen.9          2	
X wand.intro                1	
X wand_head.h               2	
X wanderer.6                1	
END_OF_MANIFEST
if test 1044 -ne `wc -c <MANIFEST`; then
    echo shar: \"MANIFEST\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f fall.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"fall.c\"
else
echo shar: Extracting \"fall.c\" \(5083 characters\)
sed "s/^X//" >fall.c <<'END_OF_fall.c'
X#include "wand_head.h"
X
Xextern void draw_symbol();
X
Xint fall(mx,my,x,y,sx,sy,screen,howdead)
Xint  x,y,sx,sy, *mx, *my;
Xchar screen[NOOFROWS][ROWLEN+1],
X     howdead[25];
X{
Xint nx = x,nyl = y,nyr = y,retval = 0;
Xif (y>(NOOFROWS-1))
X    return(0);
Xif((screen[y][x]!='O')&&(screen[y][x]!=' ')&&(screen[y][x]!='M')&&(screen[y][x]!='\\')&&(screen[y][x]!='/')&&(screen[y][x]!='@'))
X    return(0);
Xif(screen[y][x] == 'O')
X    {
X    if((screen[y][x-1] == ' ') && (screen[y-1][x-1] == ' '))
X        nx--;
X    else
X	{
X        if((screen[y][x+1] == ' ') && (screen[y-1][x+1] == ' '))
X            nx++;
X	else
X	    nx = -1;
X	}
X    if((screen[y-1][x] == ' ') && (screen[y-1][x+1] == ' '))
X        nyr--;
X    else
X	{
X        if((screen[y+1][x] == ' ') && (screen[y+1][x+1] == ' '))
X            nyr++;
X	else
X	    nyr = -1;
X	}
X    if((screen[y-1][x] == ' ') && (screen[y-1][x-1] == ' '))
X        nyl--;
X    else
X	{
X        if((screen[y+1][x] == ' ') && (screen[y+1][x-1] == ' '))
X            nyl++;
X	else
X	    nyl = -1;
X	}
X    }
Xif(screen[y][x] == '\\')
X    {
X    if(screen[y-1][++nx] != ' ')
X	nx = -1;
X    if(screen[--nyr][x+1] != ' ')
X        nyr = -1;
X    if(screen[++nyl][x-1] != ' ')
X        nyl = -1;
X    }
Xif(screen[y][x] == '/')
X    {
X    if(screen[y-1][--nx] != ' ')
X	nx = -1;
X    if(screen[++nyr][x+1] != ' ')
X	nyr = -1;
X    if(screen[--nyl][x-1] != ' ')
X	nyl = -1;
X    }
Xif((screen[y][nx] != ' ')&&(screen[y][nx] != ' '))
X    nx = -1;
Xif((screen[y-1][x] == 'O') && (nx>=0))       /* boulder falls ? */
X    {
X    screen[y-1][x] = ' ';
X    if(screen[y][nx] == '@')
X        {
X    	strcpy(howdead,"a falling boulder");  printf("\007");
X    	retval=1;
X    	}
X    if(screen[y][nx] == 'M')
X        {
X    	printf("\007");
X    	*mx = *my = -2;
X	screen[y][nx] = ' ';
X    	}
X    screen[y][nx] = 'O';
X    if((y<(sy+5)) && (y>(sy-3)) && (x>(sx-6)) && (x<(sx+6)))
X        draw_symbol((x-sx+5)*3,(y-sy+2)*2,' ');
X    if((y<(sy+4)) && (y>(sy-4)) && (nx>(sx-6)) && (nx<(sx+6)))
X        draw_symbol((nx-sx+5)*3,(y-sy+3)*2,'O');
X    refresh();
X    retval+=fall(mx,my,nx ,y+1,sx,sy,screen,howdead);
X    retval+=fall(mx,my,nx ,y+1,sx,sy,screen,howdead);
X    retval+=fall(mx,my,nx ,y+1,sx,sy,screen,howdead);
X    retval+=fall(mx,my,x+1,y-1,sx,sy,screen,howdead);
X    retval+=fall(mx,my,x-1,y-1,sx,sy,screen,howdead);
X    retval+=fall(mx,my,x  ,y-1,sx,sy,screen,howdead);
X    if(screen[y+1][nx] == '@')
X        {
X    	strcpy(howdead,"a falling boulder");  printf("\007");
X    	return(1);
X    	}
X    if(screen[y+1][nx] == 'M')
X        {
X    	printf("\007");
X    	*mx = *my = -2;
X	screen[y+1][nx] = ' ';
X    	}
X    }
Xif((screen[nyr][x] != ' ')&&(screen[nyr][x] != 'M'))
X    nyr = -1;
Xif((screen[y][x+1] == '<')&&(nyr>=0)) /* arrow moves ( < ) ? */
X    {
X    screen[y][x+1] = ' ';
X    if(screen[nyr][x] == '@')
X        {
X    	strcpy(howdead,"a speeding arrow");  printf("\007");
X    	retval = 1;
X    	}
X    if(screen[nyr][x] == 'M')
X        {
X    	printf("\007");
X    	*mx = *my = -2;
X	screen[nyr][x] = ' ';
X    	}
X    screen[nyr][x] = '<';
X    if((y<(sy+4)) && (y>(sy-4)) && (x<(sx+6)) && (x>(sx-6)))
X        draw_symbol((x-sx+6)*3,(y-sy+3)*2,' ');
X    if((nyr<(sy+4)) && (nyr>(sy-4)) && (x<(sx+7)) && (x>(sx-5)))
X        draw_symbol((x-sx+5)*3,(nyr-sy+3)*2,'<');
X    refresh();
X    retval+=fall(mx,my,x-1,nyr,sx,sy,screen,howdead);
X    retval+=fall(mx,my,x+1,y-1,sx,sy,screen,howdead);
X    retval+=fall(mx,my,x+1,y+1,sx,sy,screen,howdead);
X    retval+=fall(mx,my,x-1,y-1,sx,sy,screen,howdead);
X    retval+=fall(mx,my,x-1,y+1,sx,sy,screen,howdead);
X    retval+=fall(mx,my,x+1,y  ,sx,sy,screen,howdead);
X    if(screen[nyr][x-1] == '@')
X        {
X    	strcpy(howdead,"a speeding arrow");  printf("\007");
X    	return(1);
X    	}
X    if(screen[nyr][x-1] == 'M')
X        {
X    	printf("\007");
X    	*mx = *my = -2;
X	screen[nyr][x-1] = ' ';
X    	}
X    }
Xif((screen[nyl][x] != ' ')&&(screen[nyl][x] != 'M'))
X    nyl = -1;
Xif((screen[y][x-1] == '>')&&(nyl>=0))       /* arrow moves ( > ) ? */
X    {
X    screen[y][x-1] = ' ';
X    if(screen[nyl][x] == '@')
X        {
X    	strcpy(howdead,"a speeding arrow");  printf("\007");
X    	retval = 1;
X    	}
X    if(screen[nyl][x] == 'M')
X        {
X    	printf("\007");
X    	*mx = *my = -2;
X	screen[nyl][x] = ' ';
X    	}
X    screen[nyl][x] = '>';
X    if((y<(sy+4)) && (y>(sy-4)) && (x<(sx+6)) && (x>(sx-6)))
X        draw_symbol((x-sx+4)*3,(y-sy+3)*2,' ');
X    if((nyl<(sy+4)) && (nyl>(sy-4)) && (x<(sx+5)) && (x>(sx-7)))
X        draw_symbol((x-sx+5)*3,(nyl-sy+3)*2,'>');
X    refresh();
X    retval+=fall(mx,my,x+1,nyl,sx,sy,screen,howdead);
X	retval+=fall(mx,my,x+1,y-1,sx,sy,screen,howdead);
X	retval+=fall(mx,my,x+1,y+1,sx,sy,screen,howdead);
X	retval+=fall(mx,my,x-1,y-1,sx,sy,screen,howdead);
X	retval+=fall(mx,my,x-1,y+1,sx,sy,screen,howdead);
X    retval += fall(mx,my,x-1,y,sx,sy,screen,howdead);
X    if(screen[nyl][x+1] == '@')
X        {
X    	strcpy(howdead,"a speeding arrow");  printf("\007");
X    	return(1);
X    	}
X    if(screen[nyl][x+1] == 'M')
X        {
X    	printf("\007");
X    	*mx = *my = -2;
X	screen[nyl][x+1] = ' ';
X    	}
X    }
Xif(retval>0)
X    return(1);
Xreturn(0);
X}
END_OF_fall.c
if test 5083 -ne `wc -c <fall.c`; then
    echo shar: \"fall.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f game.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"game.c\"
else
echo shar: Extracting \"game.c\" \(14201 characters\)
sed "s/^X//" >game.c <<'END_OF_game.c'
X#include "wand_head.h"
X
X#define viable(x,y) ((screen[y][x] == ' ') || (screen[y][x] == ':') ||\
X	(screen[y][x] == '@') || (screen[y][x] == '+')) && (y >= 0) &&\
X	(x >= 0) && (y < NOOFROWS) && (x < ROWLEN)
X
Xtypedef struct mon_rec
X    {
X    int x,y,mx,my;
X    char under;
X    struct mon_rec *next;
X    };
X
Xtypedef struct { int d[2] } direction;
X
Xextern int jumpscreen();
X
Xextern void showpass();
X
Xextern void draw_symbol();
X
Xextern void display();
X
Xextern int fall();
X
Xextern void map();
X
X/* Add a spirit to the chain */
X
Xstruct mon_rec *make_monster(x,y)
Xint x,y;
X{
Xstruct mon_rec *malloc(),
X               *monster;
Xif((monster = malloc(sizeof(struct mon_rec))) == NULL)
X    return NULL;
Xmonster->x = x;
Xmonster->y = y;
Xmonster->mx = 1;      /* always start moving RIGHT. (fix later)  */
Xmonster->my = 0;
Xmonster->under = ' ';
Xmonster->next = NULL;
Xreturn monster;
X}
X
X/* 'follow lefthand wall' algorithm for sprites */
X
Xdirection new_direction(screen,x,y,bx,by)
Xint x,y,bx,by;
Xchar screen[NOOFROWS][ROWLEN+1];
X{
Xdirection out;
Xif(viable((x+by),(y-bx)))
X    {
X    out.d[0] = by;
X    out.d[1] = -bx;
X    return out;
X    }
Xif(viable((x+bx),(y+by)))
X    {
X    out.d[0] = bx;
X    out.d[1] = by;
X    return out;
X    }
Xif(viable((x-by),(y+bx)))
X    {
X    out.d[0] = -by;
X    out.d[1] = bx;
X    return out;
X    }
Xif(viable((x-bx),(y-by)))
X    {
X    out.d[0] = -bx;
X    out.d[1] = -by;
X    return out;
X    }
Xout.d[0] = -bx;
Xout.d[1] = -by;
Xreturn out;
X}
X
X/* Actual game function - Calls fall() to move
X       boulders and arrows recursively */
X
Xchar *playscreen(num,screen,score,bell,maxmoves,keys)
Xint  num, maxmoves,
X     *bell,
X     *score;
Xchar screen[NOOFROWS][ROWLEN+1],
X     keys[10];
X{
Xint  x,y,nx,ny,deadyet =0,
X     sx = -1,sy = -1,tx = -1,ty = -1,lx = 0,ly = 0,mx = -1,my = -1,
X     bx, by, nbx, nby,
X     newnum,
X     diamonds = 0, nf = 0,hd ,vd ,xdirection,ydirection;
Xchar (*frow)[ROWLEN+1] = screen,
X     ch,
X     buffer[25],
X     howdead[25];
Xdirection new_disp;
Xstruct mon_rec *monster,*mon_ptr, *current;
X
Xmon_ptr = NULL;
X
Xfor(x=0;x<=ROWLEN;x++)
X    for(y=0;y<NOOFROWS;y++)
X	{
X	if((screen[y][x] == '*')||(screen[y][x] == '+'))
X	    diamonds++;
X        if(screen[y][x] == 'A')     /* note teleport arrival point &  */
X	    {                       /* replace with space */
X	    tx = x;
X	    ty = y;
X 	    screen[y][x] = ' ';
X	    }
X        if(screen[y][x] == '@')
X	    {
X	    sx = x;
X	    sy = y;
X	    }
X        if(screen[y][x] == 'M')     /* Put megamonster in */
X	    {
X	    mx = x;
X	    my = y;
X	    }
X	if(screen[y][x] == 'S')     /* link small monster to pointer chain */
X	    {
X	    if((monster = make_monster(x,y)) == NULL)
X		{
X		strcpy(howdead,"running out of memory");
X		return howdead;
X		}
X	    if(mon_ptr == NULL)
X		current = mon_ptr = monster;
X	    else
X		current = current->next = monster;
X	    }
X        if(screen[y][x] == '-')
X        	screen[y][x] = ' ';
X        };
Xx=sx;
Xy=sy;
Xif((x == -1)&&(y == -1))              /* no start position in file ? */
X    {
X    strcpy(howdead,"a screen design error");
X    return(howdead);
X    }
Xmove(0,48);
X(void) addstr("Score\t   Diamonds");
Xmove(1,48);
X(void) addstr("\tFound\tTotal");
Xmove(3,48);
X(void) sprintf(buffer,"%d\t %d\t %d  ",*score,nf,diamonds);
X(void) addstr(buffer);
Xmove(6,48);
X(void) sprintf(buffer,"Current screen %d",num);
X(void) addstr(buffer);
Xif(maxmoves != 0)
X(void) sprintf(buffer,"Moves remaining = %d   ",maxmoves);
Xelse
X{
X    (void) strcpy(buffer,"     Unlimited moves     ");
X    maxmoves = -1;
X};
Xmove(15,48);
X(void) addstr(buffer);
Xif(mx != -1)                            /* tell player if monster exists */
X    draw_symbol(48,10,'M');
Xelse
X    draw_symbol(48,10,' ');
X
Xdisplay(sx,sy,frow,*score);
X
X/* ACTUAL GAME FUNCTION - Returns method of death in string  */
X
Xwhile(deadyet == 0)
X{
Xch = getchar();
X
Xnx=x;
Xny=y;
X
Xif(ch == keys[3])
X	nx++;
Xif(ch == keys[2])
X	nx--;
Xif((ch == keys[1]) && (y<(NOOFROWS-1)))
X	ny++;
Xif(ch == keys[0])
X        ny--;
Xif(ch == '1')
X	{
X        move(10,45);
X        *bell = 1;
X        (void) addstr("Bell ON ");
X        printf("\007");
X	move(16,0);
X        refresh();
X	}
Xif(ch == '0')
X	{
X        *bell = 0;
X        move(10,45);
X        (void) addstr("Bell OFF");
X	move(16,0);
X        refresh();
X	}
Xif(ch == '~')                             /* level jump */
X	{
X	if((newnum = jumpscreen(num)) == 0)
X	    {
X	    strcpy(howdead,"a jump error.");
X	    return howdead;
X	    }
X	if(newnum > num)
X	    {
X	    sprintf(howdead,"~%c",newnum);
X	    return howdead;
X	    }
X        printf("\007");
X	}
Xif(ch == '!')
X	{
X	map(frow);
X        display(sx,sy,frow,*score);
X	}
Xif(ch == 'q')
X        {
X        strcpy(howdead,"quitting the game");
X	return howdead;
X	}
X
Xif(screen[ny][nx] == 'C')
X    {
X    screen[ny][nx] = ':';
X    *score+=4;
X    if (*bell)
X	printf("\007");
X    if(maxmoves != -1)
X        maxmoves+=250;
X    }
Xswitch(screen[ny][nx])
X    {
X    case '@': break;
X    case '*': *score+=9;
X        if (*bell)
X	    printf("\007");
X        nf++;
X    case ':': *score+=1;
X        move(3,48);
X        sprintf(buffer,"%d\t %d",*score,nf);
X        (void) addstr(buffer);
X    case ' ':
X	screen[y][x] = ' ';
X   	screen[ny][nx] = '@';
X    	draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X    	draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
X        if(deadyet ==0)
X	    deadyet = fall(&mx,&my,x,y,sx,sy,screen,howdead);
X        if((deadyet ==0) && (nx != (x+1)))
X	    deadyet = fall(&mx,&my,x+1,y,sx,sy,screen,howdead);
X        if((deadyet ==0) && (nx != (x-1)))
X	    deadyet = fall(&mx,&my,x-1,y,sx,sy,screen,howdead);
X        if(deadyet ==0)
X	    deadyet = fall(&mx,&my,x+1,y+1,sx,sy,screen,howdead);
X        if(deadyet ==0)
X	    deadyet = fall(&mx,&my,x-1,y+1,sx,sy,screen,howdead);
X        if(deadyet ==0)
X	    deadyet = fall(&mx,&my,x-1,y-1,sx,sy,screen,howdead);
X        if((deadyet ==0) && (ny != (y+1)))
X	    deadyet = fall(&mx,&my,x,y+1,sx,sy,screen,howdead);
X        if((deadyet ==0) && (ny != (y-1)))
X	    deadyet = fall(&mx,&my,x,y-1,sx,sy,screen,howdead);
X        if(deadyet ==0)
X	    deadyet = fall(&mx,&my,x+1,y-1,sx,sy,screen,howdead);
X    	move(16,0);
X    	refresh();
X	y = ny;
X	x = nx;
X        break;
X    case 'O':
X	if(screen[y][nx*2-x] == 'M')
X	    {
X	    screen[y][nx*2-x] = ' ';
X	    mx = my = -1;
X	    if(*bell)
X		printf("\007");
X	    *score+=100;
X            move(3,48);
X            sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
X            (void) addstr(buffer);
X	    draw_symbol(48,10,' ');
X	    move(16,0);
X            refresh();
X	    }
X	if(screen[y][nx*2-x] == ' ')
X	    {
X	    screen[y][nx*2-x] = 'O';
X	    screen[y][x] = ' ';
X            screen[ny][nx] = '@';
X            draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X            draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
X            draw_symbol((nx*2-x-sx+5)*3,(y-sy+3)*2,'O');
X            if(deadyet==0)
X                deadyet = fall(&mx,&my,nx*2-x,y+1,sx,sy,screen,howdead);
X            if(deadyet==0)
X                deadyet = fall(&mx,&my,x*2-nx,y,sx,sy,screen,howdead);
X            if(deadyet==0)
X                deadyet = fall(&mx,&my,x,y,sx,sy,screen,howdead);
X            if(deadyet==0)
X                deadyet = fall(&mx,&my,x,y-1,sx,sy,screen,howdead);
X            if(deadyet==0)
X                deadyet = fall(&mx,&my,x,y+1,sx,sy,screen,howdead);
X            move(16,0);
X            refresh();
X	    y = ny;
X	    x = nx;
X	    }
X	break;
X    case '<':
X    case '>':
X	if(screen[ny*2-y][x] == 'M')
X	    {
X	    screen[ny*2-y][x] = ' ';
X	    mx = my = -1;
X	    if(*bell)
X		printf("\007");
X	    *score+=100;
X            move(3,48);
X            sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
X            (void) addstr(buffer);
X	    draw_symbol(48,10,' ');
X	    move(16,0);
X            refresh();
X	    }
X	if(screen[ny*2-y][x] == ' ')
X	    {
X	    screen[ny*2-y][x] = screen[ny][nx];
X	    screen[y][x] = ' ';
X            screen[ny][nx] = '@';
X            draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X            draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
X            draw_symbol((x-sx+5)*3,(ny*2-y-sy+3)*2,screen[ny*2-y][x]);
X            if(deadyet == 0)
X	        deadyet = fall(&mx,&my,x,y,sx,sy,screen,howdead);
X            if(deadyet == 0)
X	        deadyet = fall(&mx,&my,x-1,(ny>y)?y:(y-1),sx,sy,screen,howdead);
X            if(deadyet == 0)
X	        deadyet = fall(&mx,&my,x+1,(ny>y)?y:(y-1),sx,sy,screen,howdead);
X            if(deadyet == 0)
X	        deadyet = fall(&mx,&my,x-1,ny*2-y,sx,sy,screen,howdead);
X            if(deadyet == 0)
X	        deadyet = fall(&mx,&my,x+1,ny*2-y,sx,sy,screen,howdead);
X            move(16,0);
X            refresh();
X	    y = ny;
X	    x = nx;
X	    }
X	break;
X    case '!':
X        strcpy(howdead,"an exploding landmine");
X	deadyet = 1;
X    	draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X    	draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
X        move(16,0);
X	refresh();
X        break;
X    case 'X':
X	if(nf == diamonds)
X	    {
X	    *score+=250;
X	    if(*bell)
X		printf("\007");
X	    showpass(num);
X	    return NULL;
X	    }
X	break;
X    case 'T':
X	if(tx > -1)
X	    {
X	    screen[ny][nx] = ' ';
X	    screen[y][x] = ' ';
X	    lx = x;
X	    ly = y;
X	    y = ty;
X	    x = tx;
X	    screen[y][x] = '@';
X	    sx = x;
X	    sy = y;
X	    *score += 20;
X	    display(sx,sy,frow,*score);
X	    deadyet = fall(&mx,&my,nx,ny,sx,sy,screen,howdead);
X	    if(deadyet == 0)
X		deadyet = fall(&mx,&my,lx,ly,sx,sy,screen,howdead);
X	    if(deadyet == 0)
X		deadyet = fall(&mx,&my,lx+1,ly-1,sx,sy,screen,howdead);
X	    if(deadyet == 0)
X		deadyet = fall(&mx,&my,lx+1,ly+1,sx,sy,screen,howdead);
X	    if(deadyet == 0)
X		deadyet = fall(&mx,&my,lx-1,ly+1,sx,sy,screen,howdead);
X	    if(deadyet == 0)
X		deadyet = fall(&mx,&my,lx-1,ly-1,sx,sy,screen,howdead);
X	    move(16,0);
X	    refresh();
X	    }
X	else
X	    {
X	    screen[ny][nx] = ' ';
X	    printf("Teleport out of order");
X	    }
X	break;
X    case 'M':
X	strcpy(howdead,"a hungry monster");
X	deadyet = 1;
X    	draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X        move(16,0);
X	refresh();
X        break;
X    case 'S':
X	strcpy(howdead,"walking into a monster");
X	deadyet = 1;
X    	draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X        move(16,0);
X	refresh();
X        break;
X    default:
X        break;
X    }
Xif((y == ny) && (x == nx) && (maxmoves>0))
X    {
X    (void) sprintf(buffer,"Moves remaining = %d ",--maxmoves);
X    move(15,48);
X    (void) addstr(buffer);
X    }
Xif(maxmoves == 0)
X    {
X    strcpy(howdead,"running out of time");
X    return(howdead);
X    }
Xif ((x<(sx-3))&& (deadyet ==0))         /* screen scrolling if necessary */
X    {
X    sx-=6;
X    if(sx < 4)
X	sx = 4;
X    display(sx,sy,frow,*score);
X    }
Xif ((y<(sy-2))&& (deadyet == 0))
X    {
X    sy-=5;
X    if(sy < 2)
X	sy = 2;
X    display(sx,sy,frow,*score);
X    }
Xif ((x>(sx+3)) && (deadyet == 0))
X    {
X    sx+=6;
X    if(sx>(ROWLEN -5))
X	sx = ROWLEN -5;
X    display(sx,sy,frow,*score);
X    }
Xif ((y>(sy+2))&& (deadyet ==0))
X    {
X    sy+=5;
X    if(sy > (NOOFROWS-3))
X	sy = NOOFROWS -3;
X    display(sx,sy,frow,*score);
X    }
X
X	/* MONSTER SECTION - Put all these in a separate function later */
X
Xif(mx == -2)                              /* has the monster been killed ? */
X    {
X    *score+=100;
X    mx = my = -1;
X    move(3,48);
X    sprintf(buffer,"%d\t %d\t",*score,nf);
X    (void) addstr(buffer);
X    draw_symbol(48,10,' ');
X    move(16,0);
X    refresh();
X    }
Xif(mx != -1)                              /* no? then move that monster ! */
X    {
X    screen[my][mx] = ' ';
X    if(mx>x)
X        xdirection = -1;
X    else
X        xdirection = 1;
X    if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6)))
X        draw_symbol((mx-sx+5)*3,(my-sy+3)*2,' ');
X    if((hd = (mx-x))<0)
X	hd = -hd;
X    if((vd = (my-y))<0)
X	vd = -vd;
X    if((hd>vd)&&((screen[my][mx+xdirection] == ' ')||(screen[my][mx+xdirection] == '@')))
X	mx+=xdirection;
X    else
X        {
X        if(my>y)
X            ydirection = -1;
X	else
X    	    ydirection = 1;
X        if((screen[my+ydirection][mx] == ' ')||(screen[my+ydirection][mx] == '@'))
X	    my+=ydirection;
X	else
X            if((screen[my][mx+xdirection] == ' ')||(screen[my][mx+xdirection] == '@'))
X	mx+=xdirection;
X	}
X    if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6)))
X        draw_symbol((mx-sx+5)*3,(my-sy+3)*2,'M');
X    if(screen[my][mx] == '@')                     /* ha! gottim! */
X	{
X	strcpy(howdead,"a hungry monster");
X        move(16,0);
X	refresh();
X        return(howdead);
X	}
X    screen[my][mx] = 'M';
X    move(16,0);
X    refresh();
X    }
X
Xcurrent = monster = mon_ptr;
Xwhile((monster != NULL)&&(!deadyet))/* deal with those little monsters */
X    {
X    new_disp = new_direction(screen, monster->x, monster->y, monster->mx, monster->my );
X    screen[monster->y][monster->x] = monster->under;
X    if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)))
X        draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,monster->under);
X    if(monster->under == ' ')
X		deadyet = deadyet | fall(&mx,&my,monster->x,monster->y,sx,sy,screen,howdead);
X    monster->mx = new_disp.d[0];
X    monster->my = new_disp.d[1];
X    monster->x += monster->mx;
X    monster->y += monster->my;
X    monster->under = screen[monster->y][monster->x];
X    screen[monster->y][monster->x] = 'S';        /* move into new space */
X    if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)))
X        draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,'S');
X    if(monster->under == '@')                     /* monster hit you? */
X        {
X	strcpy(howdead,"the little monsters");
X	move(16,0);
X	refresh();
X        return(howdead);
X        }
X    if(monster->under == '+')                    /* monster hit cage? */
X        {
X	*score +=20;
X	if(*bell)
X	    printf("\007");
X        if(monster == mon_ptr)                  /* remove from chain */
X            mon_ptr = mon_ptr->next;
X  	else current->next = monster-> next;
X	screen[monster->y][monster->x] = '*';
X        if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)))
X                draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,'*');
X        }
X    if(monster->under == 'S')
X	monster->under = ' ';
X    if(monster != mon_ptr)
X        current = current->next;
X    monster = monster->next;
X    move(16,0);
X    refresh();
X    }
X
X}
Xreturn(howdead);
X}
END_OF_game.c
if test 14201 -ne `wc -c <game.c`; then
    echo shar: \"game.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f gamedev.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"gamedev.c\"
else
echo shar: Extracting \"gamedev.c\" \(14429 characters\)
sed "s/^X//" >gamedev.c <<'END_OF_gamedev.c'
X#include "wand_head.h"
X
X#define viable(x,y) ((screen[y][x] == ' ') || (screen[y][x] == ':') ||\
X	(screen[y][x] == '@') || (screen[y][x] == '+')) && (y >= 0) &&\
X	(x >= 0) && (y < NOOFROWS) && (x < ROWLEN)
X
Xtypedef struct mon_rec
X    {
X    int x,y,mx,my;
X    char under;
X    struct mon_rec *next;
X    };
X
Xtypedef struct { int d[2] } direction;
X
Xextern void draw_symbol();
X
Xextern void display();
X
Xextern int fall();
X
Xextern void map();
X
X/* Add a spirit to the chain */
X
Xstruct mon_rec *make_monster(x,y)
Xint x,y;
X{
Xstruct mon_rec *malloc(),
X               *monster;
Xif((monster = malloc(sizeof(struct mon_rec))) == NULL)
X    return NULL;
Xmonster->x = x;
Xmonster->y = y;
Xmonster->mx = 1;      /* always start moving RIGHT. (fix later)  */
Xmonster->my = 0;
Xmonster->under = ' ';
Xmonster->next = NULL;
Xreturn monster;
X}
X
X/* 'follow lefthand wall' algorithm for sprites */
X
Xdirection new_direction(screen,x,y,bx,by)
Xint x,y,bx,by;
Xchar screen[NOOFROWS][ROWLEN+1];
X{
Xdirection out;
Xif(viable((x+by),(y-bx)))
X    {
X    out.d[0] = by;
X    out.d[1] = -bx;
X    return out;
X    }
Xif(viable((x+bx),(y+by)))
X    {
X    out.d[0] = bx;
X    out.d[1] = by;
X    return out;
X    }
Xif(viable((x-by),(y+bx)))
X    {
X    out.d[0] = -by;
X    out.d[1] = bx;
X    return out;
X    }
Xif(viable((x-bx),(y-by)))
X    {
X    out.d[0] = -bx;
X    out.d[1] = -by;
X    return out;
X    }
Xout.d[0] = -bx;
Xout.d[1] = -by;
Xreturn out;
X}
X
X/* Actual game function - Calls fall() to move
X       boulders and arrows recursively */
X
Xchar *playscreen(screen,score,bell,maxmoves,keys)
Xint  maxmoves,
X     *bell,
X     *score;
Xchar screen[NOOFROWS][ROWLEN+1],
X     keys[6];
X{
Xint  x,y,nx,ny,deadyet =0,
X     sx = -1,sy = -1,tx = -1,ty = -1,lx = 0,ly = 0,mx = -1,my = -1,
X     bx, by, nbx, nby,
X     newnum, num = 1,
X     diamonds = 0, nf = 0,hd ,vd ,xdirection,ydirection;
Xchar (*frow)[ROWLEN+1] = screen,
X     ch,
X     buffer[25],
X     howdead[25];
Xdirection new_disp;
Xstruct mon_rec *monster,*mon_ptr, *current;
X
Xmon_ptr = NULL;
X
Xfor(x=0;x<=ROWLEN;x++)
X    for(y=0;y<NOOFROWS;y++)
X	{
X	if((screen[y][x] == '*')||(screen[y][x] == '+'))
X	    diamonds++;
X        if(screen[y][x] == 'A')     /* note teleport arrival point &  */
X	    {                       /* replace with space */
X	    tx = x;
X	    ty = y;
X 	    screen[y][x] = ' ';
X	    }
X        if(screen[y][x] == '@')
X	    {
X	    sx = x;
X	    sy = y;
X	    }
X        if(screen[y][x] == 'M')     /* Put megamonster in */
X	    {
X	    mx = x;
X	    my = y;
X	    }
X	if(screen[y][x] == 'S')     /* link small monster to pointer chain */
X	    {
X	    if((monster = make_monster(x,y)) == NULL)
X		{
X		strcpy(howdead,"running out of memory");
X		return howdead;
X		}
X	    if(mon_ptr == NULL)
X		current = mon_ptr = monster;
X	    else
X		current = current->next = monster;
X	    }
X        if(screen[y][x] == '-')
X        	screen[y][x] = ' ';
X        };
Xx=sx;
Xy=sy;
Xif((x == -1)&&(y == -1))              /* no start position in file ? */
X    {
X    strcpy(howdead,"no start position!");
X    return(howdead);
X    }
Xmove(0,48);
X(void) addstr("Score\t   Diamonds");
Xmove(1,48);
X(void) addstr("\tFound\tTotal");
Xmove(3,48);
X(void) sprintf(buffer,"%d\t %d\t %d  ",*score,nf,diamonds);
X(void) addstr(buffer);
Xmove(6,48);
X(void) sprintf(buffer,"Current screen %d",num);
X(void) addstr(buffer);
Xif(maxmoves != 0)
X(void) sprintf(buffer,"Moves remaining = %d   ",maxmoves);
Xelse
X{
X    (void) strcpy(buffer,"     Unlimited moves     ");
X    maxmoves = -1;
X};
Xmove(15,48);
X(void) addstr(buffer);
Xif(mx != -1)                            /* tell player if monster exists */
X    draw_symbol(48,10,'M');
Xelse
X    draw_symbol(48,10,' ');
X
Xdisplay(sx,sy,frow,*score);
X
X/* ACTUAL GAME FUNCTION - Returns method of death in string  */
X
Xwhile(deadyet == 0)
X{
Xch = getchar();
X
Xnx=x;
Xny=y;
X
Xif(ch == keys[3])
X	nx++;
Xif(ch == keys[2])
X	nx--;
Xif((ch == keys[1]) && (y<(NOOFROWS-1)))
X	ny++;
Xif(ch == keys[0])
X        ny--;
Xif(ch == '1')
X	{
X        move(10,45);
X        *bell = 1;
X        (void) addstr("Bell ON ");
X        printf("\007");
X	move(16,0);
X        refresh();
X	}
Xif(ch == '0')
X	{
X        *bell = 0;
X        move(10,45);
X        (void) addstr("Bell OFF");
X	move(16,0);
X        refresh();
X	}
Xif(ch == '~')                             /* level jump */
X        {
X	strcpy(howdead,"~~");
X        return howdead;
X	}
Xif(ch == '!')
X	{
X	map(frow);
X        display(sx,sy,frow,*score);
X	}
Xif(ch == 'q')
X        {
X        strcpy(howdead,"quitting the game");
X	return howdead;
X	}
X
Xif(screen[ny][nx] == 'C')
X    {
X    screen[ny][nx] = ':';
X    *score+=4;
X    if (*bell)
X	printf("\007");
X    if(maxmoves != -1)
X        maxmoves+=250;
X    }
Xswitch(screen[ny][nx])
X    {
X    case '@': break;
X    case '*': *score+=9;
X        if (*bell)
X	    printf("\007");
X        nf++;
X    case ':': *score+=1;
X        move(3,48);
X        sprintf(buffer,"%d\t %d",*score,nf);
X        (void) addstr(buffer);
X    case ' ':
X	screen[y][x] = ' ';
X   	screen[ny][nx] = '@';
X    	draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X    	draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
X        if(deadyet ==0)
X	    deadyet = fall(&mx,&my,x,y,sx,sy,screen,howdead);
X        if((deadyet ==0) && (nx != (x+1)))
X	    deadyet = fall(&mx,&my,x+1,y,sx,sy,screen,howdead);
X        if((deadyet ==0) && (nx != (x-1)))
X	    deadyet = fall(&mx,&my,x-1,y,sx,sy,screen,howdead);
X        if(deadyet ==0)
X	    deadyet = fall(&mx,&my,x+1,y+1,sx,sy,screen,howdead);
X        if(deadyet ==0)
X	    deadyet = fall(&mx,&my,x-1,y+1,sx,sy,screen,howdead);
X        if(deadyet ==0)
X	    deadyet = fall(&mx,&my,x-1,y-1,sx,sy,screen,howdead);
X        if((deadyet ==0) && (ny != (y+1)))
X	    deadyet = fall(&mx,&my,x,y+1,sx,sy,screen,howdead);
X        if((deadyet ==0) && (ny != (y-1)))
X	    deadyet = fall(&mx,&my,x,y-1,sx,sy,screen,howdead);
X        if(deadyet ==0)
X	    deadyet = fall(&mx,&my,x+1,y-1,sx,sy,screen,howdead);
X    	move(16,0);
X    	refresh();
X	y = ny;
X	x = nx;
X        break;
X    case 'O':
X	if(screen[y][nx*2-x] == 'M')
X	    {
X	    screen[y][nx*2-x] = ' ';
X	    mx = my = -1;
X	    if(*bell)
X		printf("\007");
X	    *score+=100;
X            move(3,48);
X            sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
X            (void) addstr(buffer);
X	    draw_symbol(48,10,' ');
X	    move(16,0);
X            refresh();
X	    }
X	if(screen[y][nx*2-x] == ' ')
X	    {
X	    screen[y][nx*2-x] = 'O';
X	    screen[y][x] = ' ';
X            screen[ny][nx] = '@';
X            draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X            draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
X            draw_symbol((nx*2-x-sx+5)*3,(y-sy+3)*2,'O');
X            if(deadyet==0)
X                deadyet = fall(&mx,&my,nx*2-x,y+1,sx,sy,screen,howdead);
X            if(deadyet==0)
X                deadyet = fall(&mx,&my,x*2-nx,y,sx,sy,screen,howdead);
X            if(deadyet==0)
X                deadyet = fall(&mx,&my,x,y,sx,sy,screen,howdead);
X            if(deadyet==0)
X                deadyet = fall(&mx,&my,x,y-1,sx,sy,screen,howdead);
X            if(deadyet==0)
X                deadyet = fall(&mx,&my,x,y+1,sx,sy,screen,howdead);
X            move(16,0);
X            refresh();
X	    y = ny;
X	    x = nx;
X	    }
X	break;
X    case '<':
X    case '>':
X	if(screen[ny*2-y][x] == 'M')
X	    {
X	    screen[ny*2-y][x] = ' ';
X	    mx = my = -1;
X	    if(*bell)
X		printf("\007");
X	    *score+=100;
X            move(3,48);
X            sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
X            (void) addstr(buffer);
X	    draw_symbol(48,10,' ');
X	    move(16,0);
X            refresh();
X	    }
X	if(screen[ny*2-y][x] == ' ')
X	    {
X	    screen[ny*2-y][x] = screen[ny][nx];
X	    screen[y][x] = ' ';
X            screen[ny][nx] = '@';
X            draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X            draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
X            draw_symbol((x-sx+5)*3,(ny*2-y-sy+3)*2,screen[ny*2-y][x]);
X            if(deadyet == 0)
X	        deadyet = fall(&mx,&my,x,y,sx,sy,screen,howdead);
X            if(deadyet == 0)
X	        deadyet = fall(&mx,&my,x-1,(ny>y)?y:(y-1),sx,sy,screen,howdead);
X            if(deadyet == 0)
X	        deadyet = fall(&mx,&my,x+1,(ny>y)?y:(y-1),sx,sy,screen,howdead);
X            if(deadyet == 0)
X	        deadyet = fall(&mx,&my,x-1,ny*2-y,sx,sy,screen,howdead);
X            if(deadyet == 0)
X	        deadyet = fall(&mx,&my,x+1,ny*2-y,sx,sy,screen,howdead);
X            move(16,0);
X            refresh();
X	    y = ny;
X	    x = nx;
X	    }
X	break;
X    case '!':
X        strcpy(howdead,"an exploding landmine");
X	deadyet = 1;
X    	draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X    	draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
X        move(16,0);
X	refresh();
X        break;
X    case 'X':
X	if(nf == diamonds)
X	    {
X	    *score+=250;
X	    if(*bell)
X		printf("\007");
X	    strcpy(howdead,"finishing the screen.");
X	    return howdead;
X	    }
X	break;
X    case 'T':
X	if(tx > -1)
X	    {
X	    screen[ny][nx] = ' ';
X	    screen[y][x] = ' ';
X	    lx = x;
X	    ly = y;
X	    y = ty;
X	    x = tx;
X	    screen[y][x] = '@';
X	    sx = x;
X	    sy = y;
X	    *score += 20;
X	    display(sx,sy,frow,*score);
X	    deadyet = fall(&mx,&my,nx,ny,sx,sy,screen,howdead);
X	    if(deadyet == 0)
X		deadyet = fall(&mx,&my,lx,ly,sx,sy,screen,howdead);
X	    if(deadyet == 0)
X		deadyet = fall(&mx,&my,lx+1,ly-1,sx,sy,screen,howdead);
X	    if(deadyet == 0)
X		deadyet = fall(&mx,&my,lx+1,ly+1,sx,sy,screen,howdead);
X	    if(deadyet == 0)
X		deadyet = fall(&mx,&my,lx-1,ly+1,sx,sy,screen,howdead);
X	    if(deadyet == 0)
X		deadyet = fall(&mx,&my,lx-1,ly-1,sx,sy,screen,howdead);
X	    move(16,0);
X	    refresh();
X	    }
X	else
X	    {
X	    screen[ny][nx] = ' ';
X	    printf("Teleport out of order");
X	    }
X	break;
X    case 'M':
X	strcpy(howdead,"a hungry monster");
X	deadyet = 1;
X    	draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X        move(16,0);
X	refresh();
X        break;
X    case 'S':
X	strcpy(howdead,"walking into a monster");
X	deadyet = 1;
X    	draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X        move(16,0);
X	refresh();
X        break;
X    default:
X        break;
X    }
Xif((y == ny) && (x == nx) && (maxmoves>0))
X    {
X    (void) sprintf(buffer,"Moves remaining = %d ",--maxmoves);
X    move(15,48);
X    (void) addstr(buffer);
X    }
Xif(maxmoves == 0)
X    {
X    addstr("You ran out of time! \007\007");
X    refresh();
X    }
Xif ((x<(sx-3))&& (deadyet ==0))         /* screen scrolling if necessary */
X    {
X    sx-=6;
X    if(sx < 4)
X	sx = 4;
X    display(sx,sy,frow,*score);
X    }
Xif ((y<(sy-2))&& (deadyet == 0))
X    {
X    sy-=5;
X    if(sy < 2)
X	sy = 2;
X    display(sx,sy,frow,*score);
X    }
Xif ((x>(sx+3)) && (deadyet == 0))
X    {
X    sx+=6;
X    if(sx>(ROWLEN -5))
X	sx = ROWLEN -5;
X    display(sx,sy,frow,*score);
X    }
Xif ((y>(sy+2))&& (deadyet ==0))
X    {
X    sy+=5;
X    if(sy > (NOOFROWS-3))
X	sy = NOOFROWS -3;
X    display(sx,sy,frow,*score);
X    }
X
X	/* MONSTER SECTION - Put all these in a separate function later */
X
Xif(mx == -2)                              /* has the monster been killed ? */
X    {
X    *score+=100;
X    mx = my = -1;
X    move(3,48);
X    sprintf(buffer,"%d\t %d\t",*score,nf);
X    (void) addstr(buffer);
X    draw_symbol(48,10,' ');
X    move(16,0);
X    refresh();
X    }
Xif(mx != -1)                              /* no? then move that monster ! */
X    {
X    screen[my][mx] = ' ';
X    if(mx>x)
X        xdirection = -1;
X    else
X        xdirection = 1;
X    if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6)))
X        draw_symbol((mx-sx+5)*3,(my-sy+3)*2,' ');
X    if((hd = (mx-x))<0)
X	hd = -hd;
X    if((vd = (my-y))<0)
X	vd = -vd;
X    if((hd>vd)&&((screen[my][mx+xdirection] == ' ')||(screen[my][mx+xdirection] == '@')))
X	mx+=xdirection;
X    else
X        {
X        if(my>y)
X            ydirection = -1;
X	else
X    	    ydirection = 1;
X        if((screen[my+ydirection][mx] == ' ')||(screen[my+ydirection][mx] == '@'))
X	    my+=ydirection;
X	else
X            if((screen[my][mx+xdirection] == ' ')||(screen[my][mx+xdirection] == '@'))
X	mx+=xdirection;
X	}
X    if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6)))
X        draw_symbol((mx-sx+5)*3,(my-sy+3)*2,'M');
X    if(screen[my][mx] == '@')                     /* ha! gottim! */
X	{
X	strcpy(howdead,"a hungry monster");
X        move(16,0);
X	refresh();
X        deadyet = 1;
X	screen[my][mx] = 'M';
X	}
X    screen[my][mx] = 'M';
X    move(16,0);
X    refresh();
X    }
X
Xcurrent = monster = mon_ptr;
Xwhile((monster != NULL)&&(!deadyet))/* deal with those little monsters */
X    {
X    new_disp = new_direction(screen, monster->x, monster->y, monster->mx, monster->my );
X    screen[monster->y][monster->x] = monster->under;
X    if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)))
X        draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,monster->under);
X    if(monster->under == ' ')
X		deadyet = deadyet | fall(&mx,&my,monster->x,monster->y,sx,sy,screen,howdead);
X    monster->mx = new_disp.d[0];
X    monster->my = new_disp.d[1];
X    monster->x += monster->mx;
X    monster->y += monster->my;
X    monster->under = screen[monster->y][monster->x];
X    screen[monster->y][monster->x] = 'S';        /* move into new space */
X    if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)))
X        draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,'S');
X    if(monster->under == '@')                     /* monster hit you? */
X        {
X	strcpy(howdead,"the little monsters");
X	move(16,0);
X	refresh();
X        deadyet = 1;
X	monster->under = ' ';
X        }
X    if(monster->under == '+')                    /* monster hit cage? */
X        {
X	*score +=20;
X	if(*bell)
X	    printf("\007");
X        if(monster == mon_ptr)                  /* remove from chain */
X            mon_ptr = mon_ptr->next;
X  	else current->next = monster-> next;
X	screen[monster->y][monster->x] = '*';
X        if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)))
X                draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,'*');
X        }
X    if(monster->under == 'S')
X	monster->under = ' ';
X    if(monster != mon_ptr)
X        current = current->next;
X    monster = monster->next;
X    move(16,0);
X    refresh();
X    }
Xif(deadyet != 0)
X    {
X    move(16,0);
X    addstr("You are dead, killed by ");
X    addstr(howdead);
X    addstr("\nPress any key to come back to life.");
X    refresh();
X    ch = getchar();
X    move(16,0);
X    addstr("                                                 \n");
X    addstr("                                                 ");
X    move(16,0);
X    refresh();
X    deadyet = 0;
X    }
X}
Xreturn(howdead);
X}
END_OF_gamedev.c
if test 14429 -ne `wc -c <gamedev.c`; then
    echo shar: \"gamedev.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f jump.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"jump.c\"
else
echo shar: Extracting \"jump.c\" \(2368 characters\)
sed "s/^X//" >jump.c <<'END_OF_jump.c'
X#include "wand_head.h"
X
Xvoid showpass(num)
Xint num;
X{
Xlong position;
Xchar correct[20];
Xchar buffer[100];
XFILE *fp;
Xchar ch;
Xmove(18,0);
Xposition = PASSWD;
Xwhile(position > 200000)
X    position -= 200000;
Xif((fp = fopen("/usr/dict/words","r")) == NULL)
X    return;
Xfseek(fp,position,ftell(fp));
Xwhile(fgetc(fp) != '\n');
Xfscanf(fp,"%s\n",correct);
X  /* read a word into correct */
Xfclose(fp);
X(void) sprintf(buffer,"\007The password to jump from level %d ( using ~ ) is : %s        \n",num,correct);
Xaddstr(buffer);
Xaddstr("PRESS ANY KEY TO REMOVE IT AND CONTINUE                          \n");
Xrefresh();
Xgetchar(ch);
Xmove(18,0);
Xaddstr("                                                                        \n");
Xaddstr("                                              ");
Xmove(18,0);
Xrefresh();
X}
X
Xint jumpscreen(num)
Xint num;
X{
Xchar word[20],
X     buffer[100],
X     correct[20];
Xint index=0, input;
Xchar ch;
Xlong position;
XFILE *fp;
Xmove(16,0);
Xsprintf(buffer,"Number of screen to jump to? (next is %d) :",num+1);
Xaddstr("Please enter password of screen to jump to:");
Xrefresh();
Xwhile(((word[index++] = getchar()) != '\n')&&(index < 19))
X    {
X    addch(' ');
X    refresh();
X    }
Xword[--index]='\0';
Xmove(16,0);
Xaddstr("Validating...                                              ");
Xrefresh();
Xposition = PASSWD;
Xwhile(position > 200000)
X    position -= 200000;
Xif((fp = fopen("/usr/dict/words","r")) == NULL)
X    return 0;
Xfseek(fp,position,ftell(fp));
Xwhile(fgetc(fp) != '\n');
Xfscanf(fp,"%s\n",correct);
X  /* read a word into correct */
X
Xfclose(fp);
X
Xif(strcmp(word,MASTERPASSWORD) == 0)
X    {
X    move(16,0);
X    sprintf(buffer,"Certainly master, but the correct word is %s.       \n",correct);
X    addstr(buffer);
X    addstr("Press letter corresponding to desired level. (Or space to continue)");
X    refresh();
X    ch = getchar();
X    num++;
X    input = ch - 'a' +1;
X    if(!(ch<'a') && !(ch>'z'))
X	num = input;
X    move(16,0);
X    addstr("                                                             ");
X    move(16,0);
X    refresh();
X    return num;
X    }
X
Xif(strcmp(correct,word) != 0)
X    {
X    move(16,0);
X    addstr("\007INCORRECT!                                 ");
X    refresh();
X    return num;
X    }
X
Xmove(16,0);
Xaddstr("Password Validated..... Jumping to next screen.           ");
Xrefresh();
X
X/* if they match, return ++num */
X
Xreturn ++num;
X}
END_OF_jump.c
if test 2368 -ne `wc -c <jump.c`; then
    echo shar: \"jump.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f mdev.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"mdev.c\"
else
echo shar: Extracting \"mdev.c\" \(1317 characters\)
sed "s/^X//" >mdev.c <<'END_OF_mdev.c'
X#include "wand_head.h"
X
Xextern char *playscreen();
X
Xint rscreen(row_ptr,maxmoves)
Xint *maxmoves;
Xchar (*row_ptr)[ROWLEN+1];
X{
Xint  y;
XFILE *fp;
Xfp = fopen("screen","r");
Xif(fp == NULL)
X    printf("File for development screen unavailable.\n\n") ;
Xelse
X    {
X    for(y = 0;y<NOOFROWS;y++)
X        {
X        fgets((*row_ptr++),ROWLEN + 1,fp);
X	fgetc(fp);                         /* remove newline char*/
X	};
X    if(fscanf(fp,"%*s\n%d",maxmoves) != 1)
X	*maxmoves=0;
X    };
Xfclose(fp);
Xreturn (fp == NULL);
X}
X
Xmain(argc,argv)
Xint  argc;
Xchar *argv[];
X{
Xchar screen[NOOFROWS][ROWLEN+1];
Xchar (*frow)[ROWLEN+1] = screen;
Xint num = 1,score = 0,bell = 1,maxmoves = 0;
Xchar howdead[25],
X     *name,*keys,*dead;
Xchar *malloc();
X
Xif((keys = (char *)getenv("NEWKEYS")) == NULL)
X    {
X    keys = malloc(5);
X    strcpy(keys,"kjhl");
X    }
X
Xinitscr();
X
X/* MAIN PROGRAM HERE */
X
Xcbreak(); noecho();
X
Xfor (;;)
X    {
X    if (rscreen(frow,&maxmoves))
X	{
X	strcpy(howdead,"a non-existant screen");
X	break;
X	};
X    dead = playscreen(screen,&score,&bell,maxmoves,keys);
X    if ((dead != NULL) && (*dead == '~'))
X	dead = NULL;
X    if (dead != NULL)
X	{
X	strcpy(howdead,dead);
X        break;
X        }
X    };
X
Xprintf("\n\nKilled by %s with a score of %d.\n",howdead,score);
X
X/* END OF MAIN PROGRAM */
X
Xecho();
Xnocbreak();
Xendwin();
Xreturn 0;
X}
END_OF_mdev.c
if test 1317 -ne `wc -c <mdev.c`; then
    echo shar: \"mdev.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f scores.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"scores.c\"
else
echo shar: Extracting \"scores.c\" \(3328 characters\)
sed "s/^X//" >scores.c <<'END_OF_scores.c'
X#include "wand_head.h"
X
X#define LOCK while((lock = creat(LOCKPATH,0)) < 0)
X#define UNLOCK (void) unlink(LOCKPATH)
X
X#define ENTRIES 15
X
Xtypedef struct
X    {
X    char howdead[25];
X    char name[20];
X    int  score;
X    int  level;
X    } score_entry;
X
Xvoid show_scores(table,num)
Xscore_entry *table;
Xint         num;
X{
Xint tot = num;
Xprintf("\nNo. Score Level           Names                 How they died\n");
Xprintf("=============================================================================\n");
Xwhile(num > 0)
X    {
X    num--;
X    printf("%2d %5d %3d      %-20s     killed by %-s\n",(tot - num),table->score,table->level,table->name,table->howdead);
X    table++;
X    }
Xprintf("\n\n");
X}
X
Xint readtable(table_ptr)
Xscore_entry *table_ptr;
X{
XFILE *fp;
Xint  numread;
Xif((fp = fopen(HISCOREPATH,"r")) == NULL)
X    {
X    numread = 0;
X    }
Xelse
X    {
X    numread = fread(table_ptr, sizeof(score_entry), ENTRIES, fp);
X    fclose(fp);
X    }
Xreturn numread;
X}
X
Xint  savescore(howdead,score,level,name)
Xchar *howdead, *name;
Xint  score,level;
X{
Xscore_entry table[ENTRIES + 2],
X	    *table_ptr = table, *from_ptr,
X	    new_entry,temp_entry;
Xint  numread,index = 1, numsaved, lock, already = 0, output_value = 1;
XFILE *fp;
Xstrncpy(new_entry.howdead,howdead,25);
Xstrncpy(new_entry.name,name,20);
Xnew_entry.score = score;
Xnew_entry.level = level;
XLOCK;
Xnumread = readtable(table_ptr);
Xif (numread > 0)
X    if(table[numread-1].score > 99999)     /* stop system errors messing it up*/
X        {
X        numread--;
X        printf("\007Erasing spurious entry in table.\n");
X        }
Xif(score == 0)
X    {
X    show_scores(table,numread);
X    UNLOCK;
X    return 0;
X    }
Xif (numread > 0) {
X	numread++;               /* scan through until correct insertion point */
X	while((table_ptr->score > score)&&(index < numread))
X	    {
X	    if(strcmp(table_ptr->name,name)==0)  {
X			already= 1;
X			break;
X			}
X	    table_ptr++;
X	    index++;
X	    }
X	if(table_ptr->score == score)
X	    while((table_ptr->level>level)&&(index<=numread)&&(table_ptr->score == score))
X	        {
X	        if((already == 1)||(strcmp(table_ptr->name,name)==0)) {
X	            already= 1;
X				break;
X			}
X	        table_ptr++;
X	        index++;
X	        };
X	if(already == 0) {                /* provided no previous hiscore */
X	    temp_entry = *table_ptr;      /* insert new entry */
X	    *table_ptr = new_entry;
X	    from_ptr = table_ptr;
X		if (strcmp(temp_entry.name, name) == 0)
X			numread--;			/* new entry directly replaces old one */
X	} else {
X	    numread--;
X	    from_ptr = table_ptr--;
X	    temp_entry = *from_ptr;
X	}
X	while(index++ < numread)
X	    {
X	    table_ptr++;
X	    from_ptr++;
X	    if(strcmp(from_ptr->name,name)==0 && index<numread) {
X			from_ptr++;
X			numread--;
X	    }
X	    new_entry = *from_ptr;
X	    *table_ptr = temp_entry;
X	    temp_entry = new_entry;
X	    }
X} else {
X    printf("\007\nCreating new hiscore table.\n\n");
X	*table_ptr = new_entry;
X	numread++;
X}
Xnumread = ( (numread > ENTRIES) ? ENTRIES : numread );
Xfp = fopen(HISCOREPATH,"w");
Xtable_ptr = table;
Xnumsaved = fwrite(table_ptr, sizeof(score_entry), numread, fp);
Xchmod(HISCOREPATH,0666);
Xif(numsaved < numread)
X    {
X    printf("ERROR! Only %d items saved from %d !\n",numsaved,numread);
X    output_value = 0;
X    }
Xfclose(fp);
XUNLOCK;
Xshow_scores(table,numsaved);
Xreturn output_value;
X}
END_OF_scores.c
if test 3328 -ne `wc -c <scores.c`; then
    echo shar: \"scores.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test ! -d screens ; then
    echo shar: Creating directory \"screens\"
    mkdir screens
fi
if test -f wand.intro -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"wand.intro\"
else
echo shar: Extracting \"wand.intro\" \(2843 characters\)
sed "s/^X//" >wand.intro <<'END_OF_wand.intro'
X                     **  W A N D E R E R  **
X                   ===========================
X
XHow to play:
X
X     Collect all the treasure:         /$\
X                                       \$/
X
X     Then go through the exit:         Way
X                                       out
X
X Keys are:  H   Left           1  Loud
X            J   Down           0  Quiet       <- Very useful!
X            K   Up             q  Quit game
X            L   Right          ~  Jump level. NB This means you do not
X***-->>     !   Look at map                      receive your bonus!
X
X     This is you:      o
X                      <|>      You are a spider.
X                            (At least, that's what you look like)
X
X
XThe other items are:
X
X  ###     -=-
X  ### and =-=    Solid rock                   <O>   Time capsule
X                                                     (5 points, 250 moves)
X   .
X  . .            Passable earth   (one point)
X
X  /^\
X  \_/            Boulder (falls down, boulders and arrows fall off it)
X
X  <--     -->    Arrows                       TTT   Cage- holds baby monsters
X  <-- and -->      (run left and right)       III    and changes into diamond
X
X  /$\                (10 points)              -o-
X  \$/            Money  (collect it)          /*\   Baby monster (kills you)
X
X  !!!      I                                 When a baby monster hits a cage
X  !!! and  o     Instant annihilation        it is captured and you get 50
X                                             points. Also the cage becomes
X                                             a diamond.
X
X
X  \_       _/    Slopes                             }o{  Monster
X    \ and /        (boulders etc slide off)         /^\     (eats you up
X                                                             whole. Yum
X  Way            The exit. Collect all the                   yum yum. )
X  out                  treasure first.                (100 points)
X                   (250 point bonus)              (kill with a rock or)
X  (*)                                                  (an arrow)
X  (*)            Teleport  (50 points for using it)
X
X       Thanx to : Mark (mjs@opal) for curing the bus error
X                  James Beckett(cstrhey) for designing screens 5 and 6
X                  Mike Taylor(maujf) for helpful suggestions
X
X         YOU CAN DEFINE YOUR OWN KEYS BY USING THE ENVIRONMENT VARIABLE
X        'NEWKEYS'. TO GET a UP z DOWN n LEFT m RIGHT ADD IN YOUR .cshrc
X         setenv NEWKEYS aznm
X         YOU CAN ALSO CHANGE YOUR NAME USING THE VARIABLE 'NEWNAME' IN THE
X         SAME WAY.
X         To see the hiscore table only, use any flag.
X   Thats the lot!   (remember, q to quit)
X
X   The idea for the game came from the games 'Repton', 'Boulderdash'
X                and 'XOR', and was then developed further.
X
X*               -Steven Shipway.
END_OF_wand.intro
if test 2843 -ne `wc -c <wand.intro`; then
    echo shar: \"wand.intro\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f wanderer.6 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"wanderer.6\"
else
echo shar: Extracting \"wanderer.6\" \(2910 characters\)
sed "s/^X//" >wanderer.6 <<'END_OF_wanderer.6'
X.TH WANDERER 6
X.SH NAME
Xwanderer - collect treasure by wandering around
X.SH SYNOPSIS
Xwanderer [-s]
X.SH DESCRIPTION
XThe object of the game is to move around, collecting treasure, and escape
Xthrough the exit.
XThe idea for the game came from the games 'Repton', 'Boulderdash'
Xand 'XOR', and was then developed further.
XUsing the
X.B -s
Xflag (or any flag, actually) can be used to view the hiscore file.
X.SH MOVING ABOUT
X.na
X.nf
X.cs R 18
X
X            H   Left           1  Loud
X            J   Down           0  Quiet       <- Very useful!
X            K   Up             q  Quit game
X            L   Right          ~  Jump level. NB This means you do not
X***-->>     !   Look at map                      receive your bonus!
X
X     This is you:      o
X                      <|>      You are a spider.
X                            (At least, that's what you look like)
X.cs R
X.ad
X.fi
X.SH OBSTACLES, MONSTERS, ETC.
X.na
X.nf
X.cs R 18
X.sp
X  ###     -=-
X  ### and =-=    Solid rock                   <O>   Time capsule
X                                                     (5 points, 250 moves)
X   .
X  . .            Passable earth   (one point)
X
X  /^\\
X  \\_/            Boulder (falls down, boulders and arrows fall off it)
X
X  <--     -->    Arrows                       TTT   Cage- holds baby monsters
X  <-- and -->      (run left and right)       III    and changes into diamond
X
X  /$\\                (10 points)              -o-
X  \\$/            Money  (collect it)          /*\\   Baby monster (kills you)
X
X  !!!      I                                 When a baby monster hits a cage
X  !!! and  o     Instant annihilation        it is captured and you get 50
X                                             points. Also the cage becomes
X                                             a diamond.
X
X
X  \\_       _/    Slopes                             }o{  Monster
X    \\ and /        (boulders etc slide off)         /^\\     (eats you up
X                                                             whole. Yum
X                                                             yum yum. )
X                                                      (100 points)
X  Way            The exit. Collect all the        (kill with a rock or)
X  out                  treasure first.                 (an arrow)
X                   (250 point bonus)
X  (*)
X  (*)            Teleport  (50 points for using it)
X.cs R
X.fi
X.ad
X.SH ENVIRONMENT VARIABLES
XYou can define your own keys for movement by using the environment
Xvariable NEWKEYS.  For eaxmaple to use a UP, z DOWN, n LEFT and m RIGHT,
Xadd
X.I setenv NEWKEYS aznm
Xto your .login or .cshrc file.  You can also change your name by using
Xthe NEWNAME environment variable.
X.SH AUTHOR
XSteven Shipway (maujp@sol.warwick.ac.uk), with thanks to:
X.br
X.na
X.nf
X	Mark (mjs@opal) for curing the bus error
X	James Beckett(cstrhey) for designing screens 5 and 6
X	Mike Taylor(maujf) for helpful suggestions
X.ad
X.fi
END_OF_wanderer.6
if test 2910 -ne `wc -c <wanderer.6`; then
    echo shar: \"wanderer.6\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 1 \(of 2\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0