DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T m

⟦d8bcfb621⟧ TextFile

    Length: 8760 (0x2238)
    Types: TextFile
    Names: »main.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/General/War/main.c« 

TextFile

static char *sccsid = "@(#)main.c	1.2	4/5/85";
static char *cpyrid = "@(#)Copyright (C) 1985 by D Bell";

/*
 * Two player war game played in mazes (by David I. Bell).
 * These war game sources are in the public domain, and can be copied
 * or used as desired, with the following restrictions:
 * 1.	All copyright notices (and this notice) must be preserved.
 * 2.	The war game sources (even if modified) cannot be sold for profit.
 * 3.	If any sources are modified, a sentence must exist by the
 *	copyright notice of each modified source file which says that
 *	the file has been modified.
 */

#include "war.h"

int	sigint();		/* interrupt signal catcher */

main(argc, argv)
	register int	argc;		/* argument count */
	register char	**argv;		/* argument name */
{
	register char	*errstr;	/* reason for option error */

	while (argc-- > 1) {
		argv++;
		if (**argv != '-') {		/* not option, must be name */
			if (enemyname) usage();
			enemyname = *argv;
			if ((argc > 1) && (argv[1][0] != '-')) {
				enemytty = *++argv;
				argc--;
			}
			continue;
		}
		errstr = NULL;
		switch (argv[0][1]) {
		case 'e':			/* just editing */
			editflag = 1;
			break;
		case 'f':			/* setup file */
			errstr = "setup file";
			setupfile = *++argv;
			argc--;
			break;
		case 'o':			/* object file */
			errstr = "object file";
			objectfile = *++argv;
			argc--;
			break;
		case 's':			/* setup name */
			errstr = "setup";
			setupname = *++argv;
			argc--;
			break;
		default:			/* errors */
			usage();
		}
		if (errstr && ((*argv == NULL) || (**argv == '-'))) {
			fprintf(stderr, "missing %s name\n", errstr);
			exit(1);
		}
	}
	if ((enemyname == NULL) && (editflag == 0)) usage();
	if (editflag == 0) findplayer(enemyname, enemytty);
	signal(SIGINT, sigint);
	if (dpyinit(NULL, NULL)) exit(1);
	scaninit(ttychar, ttyjmp);
	boardinit();				/* build the board */
	if (readobjects(objectfile)) {		/* read in objects */
		fprintf(stderr, "bad object file\n");
		exit(1);
	}
	if (readsetup(setupfile, setupname)) {	/* read in setup */
		fprintf(stderr, "cannot get setup\n");
		exit(1);
	}
	userinit();
	dpymove(0, 0);
	talkinit();				/* set up talking with enemy */
	while (1) {
		readinfo();			/* get enemy's changes */
		view();				/* show current board */
		sleep(1);			/* wait a bit */
		docommands();			/* read and execute commands */
	}
}


/*
 * Tell how to run the game and exit
 */
usage()
{
	fprintf(stderr, "\
usage:  war [-f setupfile] [-s setupname] [-o objectfile] username [ttyname]\n\
   or:  war -e [-f setupfile] [-s setupname] [-o objectfile]\n");
	exit(1);
}


/*
 * Find the object of ours with the given character.
 * Lower case letters are converted to upper case if reasonable.
 * Returns NULL if the object cannot be found.
 */
struct object *
findobject(ch)
{
	register struct	object	*obj;		/* current object */

	for (obj = objects; obj < endobjects; obj++) {
		if ((obj->o_ownch == ch) && (obj->o_side == myside)
			&& ((playing == 0) || obj->o_count))
				return(obj);
	}
	if ((ch >= 'a') && (ch <= 'z'))		/* try upper case */
		return(findobject(ch - 'a' + 'A'));
	return(NULL);
}


/*
 * Find the object which has the given id.
 * Fails if the object could not be found.
 */
struct object *
findid(id)
{
	register struct	object	*obj;	/* found object */

	for (obj = objects; obj < endobjects; obj++) {
		if (obj->o_id == id)
			return(obj);
	}
	panic("unknown object");
}


/*
 * Place an object at a particular location.  If the object is incapable
 * of being multiply placed, it is removed from its old location.
 * If another object is currently at this location, it is removed.
 * If the object can be multiply placed then a check is made to insure
 * that all multiply paced objects can be reached from the common area.
 * Returns nonzero if placement cannot be done.
 * The screen database is also updated.
 */
placeobject(obj, row, col)
	register struct	object	*obj;	/* object to place */
	unsigned int	row;		/* row to place object at */
	unsigned int	col;		/* column to place object at */
{
	register struct	cell	*cc;	/* cell location */
	register struct	object	*oldobj;/* old object at this location */

	if (obj == NULL) return(0);
	if ((row >= ROWS) || (col >= COLS)) panic("placeloc");
	/*
	 * Remove any object already at this location
	 */
	oldobj = board[row][col].c_obj;
	if (oldobj) {
		if (oldobj == obj) return(0);	/* already here */
		removeobject(row, col);
	}
	/*
	 * If we are elsewhere on the board, remove us from there
	 */
	cc = obj->o_cell;
	if (cc) {
		if (cc->c_obj != obj) panic("badcell");
		removeobject(cc->c_row, cc->c_col);
	}
	/*
	 * Put object at the current location
	 */
	cc = &board[row][col];
	cc->c_obj = obj;
	cc->c_seen = ((obj->o_side == myside) || (obj->o_flags & F_VIS));
	if (obj->o_max <= 1) obj->o_cell = cc;
	if (cc->c_seen) dpyplace(row, col, objectchar(obj));
	obj->o_count++;
	adjustdata(obj, 1);
	/*
	 * Verify that this placement is legal
	 */
	if (obj->o_side != myside) return(0);
	if ((obj->o_count > obj->o_max) || checkboard(cc)) {
		removeobject(row, col);
		placeobject(oldobj, row, col);
		return(1);
	}
	return(0);
}


/*
 * Remove an object from the board at a given coordinate.
 * The screen database is also updated.
 */
removeobject(row, col)
	unsigned int	row;		/* row to remove object from */
	unsigned int	col;		/* column to remove object from */
{
	register struct	cell	*cc;	/* cell location */
	register struct	object	*obj;	/* object to remove */

	if ((row >= ROWS) || (col >= COLS)) panic("removeloc");
	cc = &board[row][col];
	obj = cc->c_obj;
	if (obj == NULL) return;
	adjustdata(obj, -1);
	obj->o_count--;
	obj->o_cell = NULL;
	cc->c_obj = NULL;
	dpyplace(row, col, ' ');
}


/*
 * Adjust the data counts as necessary when an object is added or removed.
 * Delta is 1 if the object is being added, and -1 if the object is
 * being removed.
 */
adjustdata(obj, delta)
	register struct	object	*obj;	/* object being added/removed */
	register int	delta;		/* change to be made */
{
	register struct	data	*dp;	/* pointer to appropriate data */
	register int	flags;		/* flag bits */
	register int	deltalife;	/* total life change for object */

	dp = &hisdata;
	if (obj->o_side == myside) dp = &mydata;
	flags = obj->o_flags;
	deltalife = (obj->o_life * delta);
	if ((flags & F_IMMOB) == 0) {		/* movable men */
		dp->d_movemen += delta;
		dp->d_movelife += deltalife;
	}
	if (flags & F_FIGHT) {			/* fighting men */
		dp->d_fightmen += delta;
		dp->d_fightlife += deltalife;
	}
	if (flags & F_BLAST) {			/* blasting men */
		dp->d_blastmen += delta;
		dp->d_blastlife += deltalife;
	}
	if (flags & F_GOAL) {			/* goals */
		dp->d_goalmen += delta;
		dp->d_goallife += deltalife;
	}
	if ((flags & F_WALL) == 0) {		/* total men */
		dp->d_totalmen += delta;
		dp->d_totallife += deltalife;
	}
	if (flags & F_WALL) {			/* walls */
		dp->d_totalwalls += delta;
	}
	newstat = 1;
}


/*
 * Pick one of a specified set of directions from a cell.
 * Each applicable direction is tested using a supplied routine.
 * The routine returns nonzero if the cell in a direction is acceptable.
 * Returns the cell in the picked direction.
 */
struct cell *
pickdir(cc, dir, routine)
	register struct	cell	*cc;	/* cell to move from */
	int	dir;			/* direction to pick */
	int	(*routine)();		/* routine to decide */
{
	register struct	cell	*tc;	/* test cell */
	register int	count;		/* number of enemies */
	register int	i;		/* index */
	struct	cell	*table[4];	/* possible directions */

	switch (dir) {
		case 'h':	tc = cc->c_left; break;
		case 'j':	tc = cc->c_down; break;
		case 'k':	tc = cc->c_up; break;
		case 'l':	tc = cc->c_right; break;
		case 'a':	tc = NULL; break;
		default:	return(NULL);
	}
	if (tc) {				/* try specified direction */
		if (routine(tc) == 0) tc = NULL;
		return(tc);
	}
	for (count = 0, i = 0; i < 4; i++) {	/* search all directions */
		tc = cc->c_dirs[i];
		if (routine(tc)) table[count++] = tc;
	}
	if (count == 0) return(NULL);
	if (count > 1) count = (random() % count) + 1;
	return(table[count - 1]);
}


/*
 * Remove one hit point from an object at a given location.
 * If it goes to zero, kill the object.
 */
hitobject(row, col)
{
	register struct	object	*obj;

	obj = board[row][col].c_obj;
	if (obj == NULL) return;
	adjustdata(obj, -1);
	obj->o_life--;
	adjustdata(obj, 1);
	if (obj->o_life <= 0) removeobject(row, col);
	newstat = 1;
}


/*
 * Write a single bell to warn the user of an error
 */
beep()
{
	write(STDERR, "\7", 1);
}


/*
 * Fatal error routine
 */
panic(str)
	char	*str;
{
	dpyclose();
	fprintf(stderr, "Fatal error: %s\n", str);
	exit(1);
}


/*
 * Reset the terminal modes and exit
 */
quit(status)
{
	dpyclose();
	exit(status);
}


/*
 * Here on an interrupt to quit.
 */
sigint()
{
	dpyclose();
	exit(0);
}