|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 8760 (0x2238)
Types: TextFile
Names: »main.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/War/main.c«
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);
}