ejb@think.ARPA (Erik Bailey) (04/24/86)
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# move_to.c
# no_detect.c
# options.h
# over_stat.c
# parse.c
# This archive created: Sat Jun 8 13:01:36 1985
echo shar: extracting move_to.c '(21037 characters)'
cat << \SHAR_EOF > move_to.c
/*
* %W% (mrdch&amnnon) %G%
*/
# include "header"
# define ENEMY_FIGT sp->inventar.popul[FIGT]
int my_ships[MAXSHIPS]; /* # ships moved to attack */
movable taken; /* here we put all that we have taken */
int fighters; /* no. of attacking fighters */
planet * fp, *sp; /* the First and Second planets pointers */
int past_plan; /* how many planets did we pass */
int attack_fail[] = {
0, 0, 2, 8, 16, 25, 33, 37, 42, 44, 45, 46, 47, 48
};
int this_paint;
moveto (s)
char *s;
{
planet * tmp;
char s1[100];
int i,
j,
n,
ngate;
double dtct,
nodtct,
ftemp,
addfact;
char *spotted_ships (); /* procedure to transform vars of the * type
int[MAXSHIPS] to string */
for (j = 0; j < MAXSHIPS; j++)/* clean temp storage */
my_ships[j] = 0;
for (j = 0; j < CLASES; j++)
taken.popul[j] = 0;
taken.metals = 0;
fp = getpl (s); /* see where from */
assert_player (fp); /* is the first planet his own */
skipwhite (s); /* go to the second planet */
if (*s != '-') { /* the '-' needed to signify destination */
say ("Destination not clear, sir !!");
return;
}
else
*s = ' '; /* the function must have a ' ' at the start */
sp = getpl (s); /* identify the second planet */
if (fp == sp) {
say ("That will not change much, sir !!");
return;
}
skipwhite (s);
j = -1;
if (*s == '>') { /* a SPECIFIC direction was given */
s++;
skipwhite (s);
/* check if the direction is one allowed */
if ((j = find_direct (*s++)) < 0) {
say ("The direction specified is unclear, sir!!!");
return;
}
/* check if this direction brings us to the destination */
tmp = fp;
for (i = 0; i < 17; i++)/* can't be more than that */
if ((tmp = tmp -> gate[j]) == sp || tmp == NULL)
break;
if (tmp != sp) {
say ("In this direction we can never reach there, sir!!!");
return;
}
}
/*
* Search for the destination planet along the specified
* route. You either fall at the galaxy end, meet yourself
* again in the circle, or FIND it.
*/
if (j == -1) { /* no direction was specified */
ngate = 0;
for (i = 0; i < 10; i++) {
tmp = fp;
while ((tmp = tmp -> gate[i]))
if (tmp == sp) {
ngate++;
j = i;
break; /* see remark below */
}
else
if (tmp == fp)
break;
}
if (!ngate) {
say ("I don't see any direct route to %s, sir.", sp -> pid);
return;
}
/* If forcing the players to specify a route is desired. if (ngate > 1) {
say ("There is more then one way to get to %s, sir.", sp -> pid);
return; } */
}
ngate = j;
/* start collecting the aramade that was ordered to fly */
for (;;) {
skipwhite (s);
i = atoi (s); /* take the no. of ships */
assert_negative (i); /* see if not negative */
if (i) { /* if any was specified */
skipnum (s); /* go over it */
skipwhite (s); /* and get the type */
}
else
i = 1; /* if none given, assume 1 */
if (*s < 'a')
*s += ('a' - 'A'); /* transform them to lower */
if ((*s < 'a') || (*s > 'a' + MAXSHIPS - 1)) {
say ("The type of ship is not clear, sir!!");
return;
}
j = *s - 'a';
my_ships[j] += i;
s++;
skipwhite (s);
if (!*s) /* check if EOL reached */
break;
}
for (j = 0; j < MAXSHIPS; j++)
if (my_ships[j] > fp -> ships[j]) {
say ("But you don't have that many %c-type ships there, sir!!", j + 'A');
return;
}
n = 0; /* calculate no of fighters to fly them */
for (j = 0, i = 1; j < MAXSHIPS; j++, i *= 2)
n += NCREW / i * my_ships[j];
if (n > fp -> inventar.popul[FIGT]) {/* not enough */
say ("But sir, there are not enough fighters to fly these ships !!");
return;
}
/*
* At this point it is clear that movement is possible.
* Before doing anything else- put in a "movable"
* structure everything ordered to be moved. Update the
* source planet NOW, and the destination planet
* only after it's nature is known.
* Then check if the movement was discovered. If so-
* notify the enemy.
* If going to a friendly planet just do the house keeping.
* Else - it's WAR .
*/
/* update no. of fighters on the source planet */
fighters = n;
fp -> inventar.popul[FIGT] -= n;
/* update no. of ships */
for (j = 0; j < MAXSHIPS; j++)
fp -> ships[j] -= my_ships[j];
/* deal with the knowledge */
taken.know = fp -> to_take.know;
fp -> to_take.know = 0;
/* how much can he carry? */
n = 0;
for (j = 0; j < MAXSHIPS; j++)
n += (j + 1) * my_ships[j];
if (n >= fp -> to_take.metals) {/* enough room */
taken.metals += fp -> to_take.metals;
fp -> to_take.metals = 0;
}
else {
taken.metals += fp -> to_take.metals - n;
fp -> to_take.metals -= n;
}
/* see how many people wait */
i = 0;
for (j = 0; j < CLASES; j++)
i += fp -> to_take.popul[j];
/* and how many places */
n = 0;
for (j = 0; j < MAXSHIPS; j++)
n += VISITORS * (j + 1) * my_ships[j];
if (n >= i) /* if enough room */
for (j = 0; j < CLASES; j++) {
taken.popul[j] = fp -> to_take.popul[j];
fp -> to_take.popul[j] = 0;
}
/* NOT enough room. transfer by importance */
else
for (j = 0; n > 0; j++) {
if ((n - fp -> to_take.popul[j]) >= 0) {
n -= fp -> to_take.popul[j];
taken.popul[j] = fp -> to_take.popul[j];
fp -> to_take.popul[j] = 0;
}
else {
taken.popul[j] = n;
fp -> to_take.popul[j] -= n;
n = 0;
}
}
/* here check if the movement was discovered */
this_paint = fp -> paint; /* keep the paint. */
fp -> paint = 0; /* NONE was left at home */
/*
* Calculate effective painting.
* The rule when calculating the paint:
* More ships - easier to detect ;
* Better ships - harder to detect.
* The calculation is confined to the type of ship. i.e.
* each ship type has it's own no. indicating how
* difficult it is to detect it.
* As the ships start their voyage, the paint fades at
* the FADE_RATE per each planet past-by.
* A new factor is then calculated.
*/
addfact = 0;
for (i = 0, ftemp = 1; i < MAXSHIPS; i++, ftemp /= 2)
addfact += ftemp * my_ships[i];
nodtct = this_paint / addfact;
tmp = fp;
past_plan = 0;
do {
past_plan++; /* count the no. of planets we passed */
tmp = tmp -> gate[ngate];/* continue along the line */
this_paint = (double) this_paint * (100.- FADE_RATE) / 100.;
addfact = 0;
for (i = 0, ftemp = 1; i < MAXSHIPS; i++, ftemp /= 2)
addfact += ftemp * my_ships[i];
nodtct = this_paint / addfact;
if (tmp -> whos != fp -> whos) {
dtct = tmp -> detect;
if (dtct > nodtct) {
if (!any_force (tmp -> missile))
(void) sprintf (s1, "Sir!!! At %s we spotted %s enemy ships.", tmp -> pid, spotted_ships (my_ships));
else {
(void) sprintf (s1, "Sir!!! At %s our %s missiles encountered ", tmp -> pid, spotted_ships (tmp -> missile));
(void) sprintf (s1, "%s%s enemy ships.", s1, spotted_ships (my_ships));
}
dowrite_enemy (s1, !player);
missile_war (tmp);
if (!any_force (my_ships)) {
(void) sprintf (s1, "Sir!!! Our missiles defeated the enemy at %s!!!", tmp -> pid);
dowrite_enemy (s1, !player);
assert_loosing ();
}
}
}
} while (tmp != sp);
if (sp -> alms) /* are there any alms ? */
assert_loosing ();
/* ********************************************* */
if ((fp -> whos == sp -> whos) || (sp -> whos == 2)) {
/* forces remain in his domain or neutral captured */
/* first move the ships */
for (j = 0; j < MAXSHIPS; j++)
sp -> ships[j] += my_ships[j];
/* then the fighters */
sp -> inventar.popul[FIGT] += fighters;
/* is there knowledge to take? */
if (sp -> to_take.know < taken.know)
sp -> to_take.know = taken.know;
/* take the materials */
sp -> to_take.metals += taken.metals;
/* take the people */
for (j = 0; j < CLASES; j++)
sp -> to_take.popul[j] += taken.popul[j];
sp -> paint += this_paint;
if (sp -> whos != fp -> whos) {
say ("Congratulations, sir. We have captured that planet.");
sp -> whos = fp -> whos;
prepare_siege ();
chek_siege (sp);
return;
}
}
else {
if (ENEMY_FIGT) /* any FIGHTERS there? */
war ();
if (!any_force (my_ships)) {
(void) sprintf (s1, "Sir!!! Our forces have encountered and defeated the enemy at %s!!!", sp -> pid);
dowrite_enemy (s1, !player);
assert_loosing ();
}
capture (1, sp);
sp -> paint += this_paint;
prepare_siege ();
chek_siege (sp);
say ("Congratulations, sir!!. We have captured that planet.");
}
check_end ();
}
/* ********************************************* */
/*
* This is the WAR section.
* The results are determined by the no. and level of the
* ships involved in the battle, and also the distance
* that the attacking ships have traveled to their destination.
* The longer they traveled, the better are the chances for
* the defending forces to defeat their enemy with little
* or no lost to themselves.
*/
war () {
int i,
j,
k,
n;
int his_ships[MAXSHIPS];
int perc_fail = attack_fail[past_plan],
temp_fail;
char s1[100];
for (i = 0; i < MAXSHIPS; i++)
his_ships[i] = 0; /* clean temporary storage */
for (j = MAXSHIPS - 1, i = NCREW; j >= 0; j--, i /= 2)
while (sp -> ships[j] && ENEMY_FIGT >= NCREW / i) {
his_ships[j]++;
sp -> ships[j]--;
ENEMY_FIGT -= NCREW / i;
}
if (!any_force (his_ships))
return; /* he might not have enough soldiers */
for (j = 0; j < MAXSHIPS; j++)
while (my_ships[j] && his_ships[j]) {/* any ships */
my_ships[j]--; /* I ALWAYS loose one */
i = 100 - (rand () % 100);
if (i > perc_fail) /* if more then criterion */
his_ships[j]--; /* He looses too */
}
if (!any_force (his_ships))
return;
for (j = 1, k = 2; j < MAXSHIPS; j++, k *= 2) {
if (my_ships[j] > 0) {
i = 0;
n = k;
while (i < j) {
while (his_ships[i] >= n && my_ships[j]) {
my_ships[j]--;/* I loose */
temp_fail = 100 - (rand () % 100);
if (temp_fail > perc_fail)
his_ships[i] -= n;/* He too */
}
if (my_ships[j])
his_ships[i] = 0;
i++;
n /= 2;
}
}
else
if (his_ships[j] > 0) {
i = 0;
n = k;
while (i < j) {
while (my_ships[i] >= n && his_ships[j]) {
my_ships[i] -= n;
temp_fail = 100 - (rand () % 100);
if (temp_fail > perc_fail)
his_ships[j]--;
}
if (his_ships[j])
my_ships[i] = 0;
i++;
n /= 2;
}
}
}
if (!any_force (his_ships))
return;
/* none left from My forces. we're doomed */
n = 0; /* calculate no of fighters left to him */
for (j = 0, i = 1; j < MAXSHIPS; j++, i *= 2) {
sp -> ships[j] += his_ships[j];
n += NCREW / i * his_ships[j];
}
ENEMY_FIGT += n;
(void) sprintf (s1, "Sir!!! Our forces have encountered and defeated the enemy at %s!!!", sp -> pid);
dowrite_enemy (s1, !player);
assert_loosing ();
}
missile_war (pp)
planet * pp;
{
int i,
j,
k,
n;
char s1[100];
int destroyed[MAXSHIPS];/* # of ships destroyed */
if (!any_force (pp -> missile))
return; /* the defender has no missiles there */
for (j = 0; j < MAXSHIPS; j++)
destroyed[j] = 0; /* all ships are intact (so far...) */
for (j = 0; j < MAXSHIPS; j++)
while (my_ships[j] && pp -> missile[j]) {/* any ships */
my_ships[j]--; /* I ALWAYS loose one */
destroyed[j]++; /* remember what I lost */
pp -> missile[j]--; /* He looses too */
}
if (!any_force (pp -> missile)) {
/* The battle has been fought, tell the owner of the missiles */
(void) sprintf (s1, "Sir!!! Our missiles destroyed the enemy ships: %s.", spotted_ships (destroyed));
dowrite_enemy (s1, !player);
return;
}
for (j = 1, k = 2; j < MAXSHIPS; j++, k *= 2) {
if (my_ships[j] > 0) {
i = 0;
n = k;
while (i < j) {
while (pp -> missile[i] >= n && my_ships[j]) {
my_ships[j]--;
destroyed[j]++;
pp -> missile[i] -= n;
}
if (my_ships[j])
pp -> missile[i] = 0;
i++;
n /= 2;
}
}
else
if (pp -> missile[j] > 0) {
i = 0;
n = k;
while (i < j) {
while (my_ships[i] >= n && pp -> missile[j]) {
my_ships[i] -= n;
destroyed[j] += n;
pp -> missile[j]--;
}
if (pp -> missile[j]) {
destroyed[i] = my_ships[i];
my_ships[i] = 0;
}
i++;
n /= 2;
}
}
}
/* The battle has been fought, tell the owner of the missiles */
(void) sprintf (s1, "Sir!!! Our missiles destroyed the enemy ships: %s.", spotted_ships (destroyed));
dowrite_enemy (s1, !player);
}
/*
* Here when landing on a unarmed enemy's teritory
* or when winning a battle.
*/
capture (force, sp)
int force;
planet * sp;
{
int i,
j,
k,
m,
n,
n1,
n2;
sp -> whos = fp -> whos; /* now it is MINE */
free_reports (sp -> reports);/* the reports are not actual */
sp -> secur = 0; /* no security is valid */
if (force) {
sp -> paint = 0; /* if paint was left-destroy */
sp -> detect = 0; /* if detection left-destroy */
for (j = 0; j < MAXSHIPS; j++)
sp -> missile[j] = 0;
}
for (j = 0; j < ESPSIZ; j++)
for (m = 0; m < ESPTYP; m++)
for (k = 0; k < 2; k++)
sp -> espion[k][m][j] = 0;/* and no espionage yet */
/* first move the forces */
for (j = 0; j < MAXSHIPS; j++)
sp -> ships[j] = my_ships[j];
/* how much metal can he carry? */
n = 0;
for (j = 0; j < MAXSHIPS; j++)
n += (j + 1) * my_ships[j];
if (n >= taken.metals) /* enough room */
sp -> to_take.metals += taken.metals;
else
sp -> to_take.metals += n;
/* when dealing with knowledge, it is ALWAYS transfered */
if (force) {
sp -> to_take.know = taken.know;
sp -> inventar.know = taken.know;
}
/* now deal with the people */
n2 = sp -> to_take.popul[SLAV];/* keep them. they were yours */
sp -> to_take.popul[SLAV] = 0;
/* add all the to_be_transfered people */
for (j = 0, n1 = 0; j < CLASES; j++) {
n1 += sp -> to_take.popul[j];
sp -> to_take.popul[j] = 0;
}
sp -> to_take.popul[CITI] = n2;
sp -> to_take.popul[SLAV] = n1;/* put them correctly now */
/* see how many people wait */
i = 0;
for (j = 0; j < CLASES; j++)
i += taken.popul[j];
/* and how many places */
n = 0;
for (j = 0; j < MAXSHIPS; j++)
n += VISITORS * (j + 1) * my_ships[j];
if (n >= i) /* if enough room */
for (j = 0; j < CLASES; j++) {
sp -> to_take.popul[j] += taken.popul[j];
}
/* NOT enough room. transfer by importance */
else
for (j = 0; n > 0; j++) {
if ((n - taken.popul[j]) >= 0) {
n -= taken.popul[j];
sp -> to_take.popul[j] += taken.popul[j];
}
else {
sp -> to_take.popul[j] += n;
n = 0;
}
}
/* now deal with the people that are stationed on the planet */
n2 = sp -> inventar.popul[SLAV];/* keep them. they were yours */
sp -> inventar.popul[SLAV] = 0;
/* add all the to_be_transfered people */
for (j = 0, n1 = 0; j < CLASES; j++) {
n1 += sp -> inventar.popul[j];
sp -> inventar.popul[j] = 0;
}
sp -> to_take.popul[CITI] += n2;
sp -> inventar.popul[SLAV] = n1;/* put them correectly now */
n = 0; /* calculate no of fighters left to me */
for (j = 0, i = 1; j < MAXSHIPS; j++, i *= 2)
n += NCREW / i * my_ships[j];
ENEMY_FIGT = n;
}
/* this recursive functions frees all the information that
* was gathered about a captured planet. Naturly, it is not valid
* anymore. */
free_reports (prvinfo)
info * prvinfo;
{
if (prvinfo == 0)
return; /* end of list. */
free_reports (prvinfo -> next);
ifree (prvinfo);
}
/* check to see if any forces left */
any_force (ship)
int *ship;
{
int n,
j;
n = 0;
for (j = 0; j < MAXSHIPS; j++)
if (*ship++)
n++;
return (n);
}
/* this function prepares for the siege checking */
prepare_siege () {
int i;
fighters = 0;
taken.know = 0;
taken.metals = 0;
for (i = 0; i < CLASES; i++)
taken.popul[i] = 0;
for (i = 0; i < MAXSHIPS; i++)
my_ships[i] = 0;
}
/*
* This function checks to see if by capturing a planet
* a siege was completed around one of the enemy's planets.
* Each surrounding planet is scanned, and if it belongs to
* the enenmy, it's surroundings is scanned. If all the
* planets belong to the PLAYER, it is considered captured.
* In contrast to direct taking by force, all except the ships
* remain intact.
*/
chek_siege (pp)
planet * pp;
{
char s[100];
int i,
j,
np;
planet * tmp1, *tmp2;
for (i = 0; i < 10; i++)
if ((tmp1 = pp -> gate[i]) && (tmp1 -> whos == !player)) {
for (j = 0, np = 0; j < 10; j++)
if ((tmp2 = tmp1 -> gate[j]) && (tmp2 -> whos != player))
np++;
if (!np) { /* he is totaly surrounded */
capture (0, tmp1);
(void) sprintf (s, "Sir!!! we have taken %s planet too!!!", tmp1 -> pid);
dowrite_enemy (s, player);
}
}
}
/* This procedure transforms an integer array with ship counts in */
/* a string listing the amounts of the different ships */
/* The array [3,2,0,1,0,0,...,0] would be transformed to the */
/* string " 3A 2B 1D" . */
char *spotted_ships (ship)
int *ship;
{
static char s[100]; /* The list of ships; e.g. " 3A 2B 1D" */
int j;
s[0] = '\0';
for (j = 0; j < MAXSHIPS; j++) {
if (*ship)
(void) sprintf (s, "%s %d%c", s, *ship, 'A' + j);
ship++;
}
return (s);
}
SHAR_EOF
if test 21037 -ne "`wc -c move_to.c`"
then
echo shar: error transmitting move_to.c '(should have been 21037 characters)'
fi
echo shar: extracting no_detect.c '(726 characters)'
cat << \SHAR_EOF > no_detect.c
/*
* %W% (mrdch&amnnon) %G%
*/
# include "header"
nodetect (s)
char *s;
{
planet * pp;
int i;
pp = getpl (s); /* get planet id */
assert_player (pp); /* see if legal planet + owner */
skipwhite (s); /* go to the money part */
i = atoi (s); /* take the amount */
assert_money (i); /* see if there is enough of it */
skipword (s); /* skip that no. */
assert_end (s); /* does it end good?? */
pp -> paint += i; /* raise the paint */
teller[player] -= i; /* take his money */
}
SHAR_EOF
if test 726 -ne "`wc -c no_detect.c`"
then
echo shar: error transmitting no_detect.c '(should have been 726 characters)'
fi
echo shar: extracting options.h '(50 characters)'
cat << \SHAR_EOF > options.h
/*
* %W% (mrdch&amnnon) %G%
*/
# define ENQDBG
SHAR_EOF
if test 50 -ne "`wc -c options.h`"
then
echo shar: error transmitting options.h '(should have been 50 characters)'
fi
echo shar: extracting over_stat.c '(10506 characters)'
cat << \SHAR_EOF > over_stat.c
/*
* %W% (mrdch&amnnon) %G%
*/
# include "header"
overstat (s)
char *s;
{
planet * pp;
int i,
j;
int all_popul[CLASES]; /* to count the entire population */
int myships[MAXSHIPS]; /* to count the ships inventory */
int mymissile[MAXSHIPS];/* to count the missile inventory */
int nplanets[PLKINDS + 1];/* to count planet's situation */
int nalms = 0; /* to count the alms */
int nmetals = 0; /* to count the metal digged */
int maxknow = -1; /* the no. of planet with max know */
char cc;
static char owner = 'O';
static char black = '?';
static char force = '!';
static char specl = '+';
static char alms = '~';
static char fight = '^';
static char build = '&';
static char dinfo = 'I';
static char spies = 'S';
static char detec = 'T';
static char paint = '%';
static char missl = 'M';
skipwhite (s);
if (*s == '\0') {
flip ();
clear ();
for (i = 0; i < CLASES; i++)
all_popul[i] = 0;
for (i = 0; i < MAXSHIPS; i++) {
myships[i] = 0;
mymissile[i] = 0;
}
for (i = 0; i <= PLKINDS; i++)
nplanets[i] = 0;
for (i = 0, pp = &pl[0]; i < MAXPL; i++, pp = &pl[i])
if (pp -> whos == player) {
nplanets[PLKINDS]++;
nalms += pp -> alms;/* add total alms */
nmetals += pp -> inventar.metals;/* add total metals */
if (maxknow == -1)
maxknow = i;
if (pl[maxknow].inventar.know < pl[i].inventar.know)
maxknow = i;/* update max knowledge */
if (pp -> inventar.popul[FIGT])
nplanets[FIGT]++;
if (pp -> inventar.popul[CITI])
nplanets[CITI]++;
if (pp -> inventar.popul[MINE])
nplanets[MINE]++;
if (pp -> inventar.popul[BUIL])
nplanets[BUIL]++;
if (pp -> inventar.popul[SCIE])
nplanets[SCIE]++;
for (j = 0; j < CLASES; j++) {
all_popul[j] += pp -> inventar.popul[j];
all_popul[j] += pp -> to_take.popul[j];
}
for (j = 0; j < MAXSHIPS; j++) {
myships[j] += pp -> ships[j];
mymissile[j] += pp -> missile[j];
}
}
pos (0, 28);
print ("Overall situation report");
pos (1, 28);
print ("========================\r\n");
print ("Population: %d\r\n", count_popul (player));
for (j = 0; j < CLASES; j++)
if (all_popul[j])
print ("%6d %s\r\n", all_popul[j], ocup_name[j]);
pos (11, 0);
print ("Planets situation:\r\n");
print ("%6d controlled planets\r\n", nplanets[PLKINDS]);
print ("%6d Military bases.\r\n", nplanets[FIGT]);
print ("%6d Agricultural planets.\r\n", nplanets[CITI]);
print ("%6d Mining planets.\r\n", nplanets[MINE]);
print ("%6d Industrial planets. \r\n", nplanets[BUIL]);
print ("%6d Scientific planets.\r\n", nplanets[SCIE]);
j = 3;
pos (j++, 38);
print ("No. of ships and missiles:");
for (i = 0; i < MAXSHIPS; i++)
if (myships[i] || mymissile[i]) {
pos (j++, 35);
print ("%c-type %4d ships %4d missiles.",
i + 'A', myships[i], mymissile[i]);
}
j++;
pos (j++, 35);
print ("Invested in trade %d Tellers.", trade[player]);
pos (j++, 35);
print ("Feeding the population with %d Tellers.",
food[player]);
pos (j++, 35);
print ("Total of %d ALMs were laid.", nalms);
pos (j++, 35);
print ("Total of %d A-type metal quantities.", nmetals);
pos (j++, 35);
print ("The best knowledge is %c in planet %s.",
'A' + pl[maxknow].inventar.know, pl[maxknow].pid);
more ();
return;
}
/*
* owner = 'O' ;
* black = '?' ;
* force = '!' ;
* specl = '+' ;
* alms = '~' ;
* fight = '^' ;
* build = '&' ;
* dinfo = 'I' ;
* spies = 'S' ;
* detec = 'T' ;
* paint = '%' ;
* missl = 'M' ;
*
* The chars used are: n o a s b f F c k e i d p m
* Their attributes: O ~ + ? ! ^ & A-G S I T % M
*/
while ((cc = *s++)) {
switch (cc) {
case 'n': /* clean the screen from all attributes */
clean_attr ();
break;
case 'o': /* show in reverse planets he owns */
for (i = 0; i < MAXPL; i++)
if (pl[i].whos == player)
change_attr (owner, i);
else
check_attr (owner, i);
break;
case 'p': /* show where detecting devices exist */
for (i = 0; i < MAXPL; i++)
if (pl[i].whos == player)
if (pl[i].paint)
change_attr (paint, i);
else
check_attr (paint, i);
break;
case 'd': /* show where detecting devices exist */
for (i = 0; i < MAXPL; i++)
if (pl[i].whos == player)
if (pl[i].detect)
change_attr (detec, i);
else
check_attr (detec, i);
break;
case 'a': /* show planets he owns with alm */
for (i = 0; i < MAXPL; i++)
if (pl[i].whos == player)
if (pl[i].alms)
change_attr (alms, i);
else
check_attr (alms, i);
break;
case 's': /* show special planets */
for (i = 0; i < MAXPL; i++)
if (pl[i].whos == player) {
j = pl[i].inventar.popul[CITI] != 0;
j = j || (pl[i].inventar.popul[MINE] != 0);
j = j || (pl[i].inventar.popul[BUIL] != 0);
j = j || (pl[i].inventar.popul[SCIE] != 0);
if (j)
change_attr (specl, i);
else
check_attr (specl, i);
}
break;
case 'b': /* show blanked planets */
for (i = 0; i < MAXPL; i++)
if (pl[i].whos == player)
if (pl[i].secur)
change_attr (black, i);
else
check_attr (black, i);
break;
case 'f': /* show where his forces are */
for (i = 0; i < MAXPL; i++)
if (pl[i].whos == player) {
j = 0;
while (!pl[i].ships[j] && j < MAXSHIPS)
j++;
if (j < MAXSHIPS)
change_attr (force, i);
else
check_attr (force, i);
}
break;
case 'm': /* show where his missiles are */
for (i = 0; i < MAXPL; i++)
if (pl[i].whos == player) {
j = 0;
while (!pl[i].missile[j] && j < MAXSHIPS)
j++;
if (j < MAXSHIPS)
change_attr (missl, i);
}
break;
case 'F': /* show where he has fighters */
for (i = 0; i < MAXPL; i++)
if (pl[i].whos == player) {
if (pl[i].inventar.popul[FIGT])
change_attr (fight, i);
else
check_attr (fight, i);
}
break;
case 'c': /* show where building of ships is done */
for (i = 0; i < MAXPL; i++)
if (pl[i].whos == player) {
if (pl[i].to_build[BUILD_MONEY] || pl[i].to_build[NSHIPS])
change_attr (build, i);
else
check_attr (build, i);
}
break;
case 'k': /* show other then A level of knowledge */
for (i = 0; i < MAXPL; i++)
if (pl[i].whos == player) {
if (pl[i].inventar.know)
change_attr ('A' + pl[i].inventar.know, i);
else
if (pl[i].d_symbol[player] >= 'A' &&
pl[i].d_symbol[player] <= 'A' + MAXSHIPS)
change_attr (pl[i].symbol, i);
}
break;
case 'i': /* show where you have messages */
for (i = 0; i < MAXPL; i++)
if (count_msgs (pl[i].reports, player))
change_attr (dinfo, i);
else
check_attr (dinfo, i);
break;
case 'e': /* show to which planet you have send
spies */
for (i = 0; i < MAXPL; i++)
if (count_spies (&pl[i], player))
change_attr (spies, i);
else
check_attr (spies, i);
break;
default:
return;
}
}
}
clean_attr () {
int i;
for (i = 0; i < MAXPL; i++)
change_attr (pl[i].symbol, i);
}
change_attr (cc, i)
char cc;
int i;
{
if (pl[i].d_symbol[player] != cc) {
pl[i].d_symbol[player] = cc;
pos (pl[i].coord[0], pl[i].coord[1] + 1);
disch (cc);
}
}
check_attr (cc, i)
char cc;
{
if (pl[i].d_symbol[player] == cc)
change_attr (pl[i].symbol, i);
}
SHAR_EOF
if test 10506 -ne "`wc -c over_stat.c`"
then
echo shar: error transmitting over_stat.c '(should have been 10506 characters)'
fi
echo shar: extracting parse.c '(16496 characters)'
cat << \SHAR_EOF > parse.c
/*
* %W% (mrdch&amnnon) %G%
*/
# include "header"
/* if a restored game switched players i.d. */
extern SWITCH_FLAG;
extern nulluser;
extern int no_new_year;
char moreflg[2] = TWOZERO;
/* flag to indicate if player changed during game */
char didchange[2] = TWOZERO;
int changestat;
planet * curpln;
int overstat (), retrieve (), pversion (),
getoutofhere (), restorgame (), savegame (), takepl (),
endgame (), quit (), give_up (), planetsit (), planetenq (),
blackout (), assign (), feedpop (), takefrom (), moveto (),
detectmv (), nodetect (), leaveat (), trading (), putalm (),
init_disc (), killalm (), write_enemy (), build (),
set_missile (), help (), menu (), next_year (), wizwiz (),
no_new (), toggle_wizard (), changeplay ();
struct commands {
char *str; /* the command name */
int (*cfun) (); /* the function that executes it */
char *docname; /* the file name that documents it */
char *exp; /* a short explanation */
};
struct commands ctab[] = {
"os", overstat, "overstat",
"Overall Situation. os || os [abcdefFikmnops]",
"ps", planetsit, "plansit",
"Planet Situation. ps [plid] [i]",
"as", assign, "assign",
"Assign people. as [plid] N (cfmbs) (cfmbs)",
"en", planetenq, "planenq",
"Enquire Planet. en [plid] [level] (afkmpst) T",
"bo", blackout, "blackout",
"Blackout a Planet. bo [plid] T",
"tk", takefrom, "takefrom",
"Take from. tk [plid] (k) || (N (tcfmbsv) )",
"lv", leaveat, "leave_at",
"Leave at. lv [plid] (k || K) || (N (tcfmbsv) )",
"mv", moveto, "move_to",
"Move to. mv [plid] -[plid] [>dr] NH [NH NH ...]",
"bs", build, "build",
"Build new ships. bs [plid] NH T || bs [plid] t T",
"sm", set_missile, "set_missl",
"Set missiles. sm [plid] NH",
"dt", detectmv, "detect",
"Detect movement / Paint ships. dt/nd [plid] T",
"nd", nodetect, "paint", 0,
"lm", putalm, "putalm",
"Lay ALM. lm [plid] N",
"dm", killalm, "killalm",
"Deactivate ALM. dm [plid] N",
"fd", feedpop, "feedpop",
"Feed population. fd T",
"tr", trading, "trade",
"Trade. tr T",
"rt", retrieve, "retrieve",
"Retrieve invested money. rt T (tfbs) [plid]",
"wr", write_enemy, "write",
"Write to the enemy. wr [anything....+ return]",
"mp", init_disc, "init_dis",
"Refresh the screen. mp",
"ny", next_year, "next_year",
"Jump a year/Continue stoped game. ny",
"nn", no_new, "next_year",
"Stop game for a while. nn",
"sv", savegame, "savegame",
"Save / Restore Game. sv/rs (file name)",
"rs", restorgame, "restor", 0,
"gu", give_up, "give_up",
"Give up this game / Ask to quit. gu/qt",
"qt", quit, "quit", 0,
"menu", menu, 0, 0,
"help", help, "help", 0,
"man", help, "help", 0,
"version", pversion, 0, 0,
"cp", changeplay, "chng_ply", "# Change player",
"wz", wizwiz, 0, "# Get a lot of everything",
"capt", takepl, 0, "# Take any planet you wish",
"toggle", toggle_wizard, 0, "# Give up/regain wizardcy",
"getout", getoutofhere, 0, "# Exit the game neatly and QUICK!!",
0, 0, 0, 0
};
/*
* this funstion sets the active terminal to the required .
*/
termn (n) {
if (SWITCH_FLAG) /* in a restored game, player switched */
n = !n;
if (n == 0) {
term0 ();
}
else {
term1 ();
}
/* check if cp command was given */
if (didchange[n]) {
player = !player;
changestat = 1;
}
else
changestat = 0;
/* set the current planet to the active player */
if (!player)
curpln = spntr;
else
curpln = apntr;
}
#define GETSTRMODE 1
#define CURSORMODE 2
/* in these buffers the input from both players is gathered */
char bufs[2][100];
/* pointers into the buffers */
int bufsp[2] = TWOZERO;
/* flags to the current position of player */
int mode[2] = {
CURSORMODE, CURSORMODE
};
/*
* The main loop. Reads chars from the two processes, stores
* them in bufs, and interprets the command. When a legal
* command is found, the function associated with that command
* is invoked. The nature of this program requires that ALL
* the relevant information to a specific command to be known
* at the time of it's execution. (Any busy wait loop will cause
* stagnation for the SECOND player).
*/
parse () {
struct commands *c = ctab;
char *ch;
chan x;
/* initialize first terminal */
termn (0);
if (ctrlinit () == 0);
crmode ();
noecho ();
say ("Sir. If you feel somewhat lost, give the \"help\" command.");
cleol (22, 11);
/* initialize second terminal */
termn (1);
if (ctrlinit () == 0);
crmode ();
noecho ();
say ("Sir. If you feel somewhat lost, give the \"help\" command.");
cleol (22, 11);
/* enter main loop */
getcommand:
for (;;) {
c = ctab;
(void) fflush (ttys[0]);
(void) fflush (ttys[1]);
if (readc (&x) != sizeof (x))
bug ("read error on pipe.");
termn (x.ichan); /* set terminal to where it came from */
/*
* First check if it's in "more" mode .
* In that case, flip back on request.
*/
if (moreflg[player]) {
if (x.c != ' ' && x.c != '5')
goto getcommand;
endmore ();
putmsgs ('r'); /* regular printout */
prteller ();
goto getcommand;
}
/* esc char toggles the two stages */
if (x.c == '\033') { /* ascii esc */
if (mode[player] == GETSTRMODE) {
mode[player] = CURSORMODE;
curse_map (curpln);
}
else {
mode[player] = GETSTRMODE;
curse_com (curpln);
cleol (22, 11 + bufsp[player]);
}
goto getcommand;
}
/* in the map mode, movement and message command and given */
if (mode[player] == CURSORMODE) {
if (x.c == '-' || x.c == ' ') {/* delete messages stack */
putmsgs ('-'); /* to advance rapidly */
curse_map (curpln);
goto getcommand;
}
/* good for ascii only. */
if ((x.c > '9') || iscntrl (x.c)) {
curse_com (curpln);
mode[player] = GETSTRMODE;
cleol (22, 11 + bufsp[player]);
}
else {
changeloc (x.c);
goto getcommand;
}
}
if (mode[player] == GETSTRMODE) {
if (x.c == '\n' || x.c == '\r') {
mode[player] = CURSORMODE;
bufs[player][bufsp[player]] = '\0';
ch = bufs[player];
bufsp[player] = 0;
goto parse;
}
else /* collect the chars */
dogetstr (x.c);
}
}
/* find out which command was given */
parse:
if (*ch) {
if (Pause) {
/* were having a pause. Execute harmless commands (no movements) */
if (strncmp (ch, "mv", 2) == 0) {
say ("As we take a break, I cannot move a single ship, sir.");
cleol (22, 11);
goto getcommand;
}
}
while (c -> str != 0) {
cleol (23, 0);
if (strcmpn (ch, c -> str, strlen (c -> str)) == 0) {
/* enable quick return in case of error */
if (setjmp (jparse) == 0)
(*c -> cfun) (ch + strlen (c -> str));
/* update time */
if (!Pause)
softclock (0);
if (!moreflg[player]) {
cleol (22, 11);
putmsgs ('r');/* regular */
prteller ();
}
goto getcommand;
}
c++;
}
error ();
c = ctab;
goto getcommand;
}
goto getcommand;
}
extern int month; /* the x/100 of the year */
prteller () {
char s[10];
cleol (19, 0);
pr_at (19, 4, "Planet: %s", curpln -> pid);
pos (19, 25);
if (teller[player])
print ("You have %d Tellers left, sir.", teller[player]);
else
print ("No money left, sir. So sorry..");
if (month < 10)
(void) sprintf (s, "%c%d", '0', month);
else
(void) sprintf (s, "%d", month);
if (wants_newy[player])
pr_at (19, 62, "NY");
pr_at (19, 65, "Year : %d.%s", year, s);
curse_map (curpln);
}
changeloc (dir)
char dir;
{
int j;
/* if the terminal has the capability, flip the page over */
if (dir == '5')
if (ttyc -> t_fl != 0) {
flip ();
more ();
return;
}
if ((j = find_direct (dir)) < 0)
return; /* illegal direction */
if (curpln -> gate[j] == NULL)
return;
curpln = curpln -> gate[j];
if (!player)
spntr = curpln;
else
apntr = curpln;
pr_at (19, 12, "%s", curpln -> pid);
/* update position at screen */
curse_map (curpln);
}
/*
* This function prints a message and sleeps until a character
* is striked at the terminal which executed more.
*
* The problem is that we can't wait to a character here becaue
* we want to get a character from the other terminal.
*
* We can use the fact that all the functions
* using more() call it just before they return to parse.
* More will simply set a flag to tell parse that we are in
* more mode.
*/
more () {
so (23, 56, "Hit SPACE to continue");
(void) fflush (tty);
moreflg[player] = 1;
}
endmore () {
cleol (23, 0); /* clear the "more" message */
moreflg[player] = 0;
flip ();
}
/*
* Get online help. All the commands that are listed above
* have help files associated with them. In case that information
* is required about some general issues, the requested file is
* searced. Actually, all the manual can be obtained in that
* fashion.
*/
help (s)
char *s;
{
FILE * docfile;
char nwcm[200];
struct commands *c = ctab;
skipwhite (s);
if (*s == '\0') { /* no patrameters were given */
strcpy (nwcm, "help");
help (nwcm); /* call recursivly with arg */
return;
}
if (*s == '-') { /* a general information was requested */
(void) sprintf (nwcm, "%s%s.doc", ONLINE, ++s);
goto show_doc;
}
while (c -> str != 0) { /* didn't reach the last command */
if (strncmp (s, c -> str, strlen (c -> str)) == 0) {
if (c -> docname == 0)
break;
(void) sprintf (nwcm, "%s%s.doc", ONLINE, c -> docname);
show_doc: docfile = fopen (nwcm, "r");
if (docfile == NULL) {
say ("I think you have the wrong name, sir. Try \"help\".");
return;
}
flip ();
clear ();
while (fgets (nwcm, 200, docfile) != NULL)
print ("%s\r", nwcm);
(void) fclose (docfile);
more ();
return;
}
c++;
}
say ("But sir !!! I don't understand that command. Try \"menu\".");
}
/*
* Extract from the command structure the information concerning
* the syntax of the commands.
*/
menu (s)
char *s;
{
struct commands *c = ctab;
int wiz = 0;
skipwhite (s);
if (*s == 'w') {
assert_wizard ();
wiz = 1;
}
flip ();
clear ();
if (!wiz)
print ("<plid = planet id> <N = no.> <T = Tellers> <H = ship type> <dr = direction>");
else
print ("This commands are only yours to give, dear lord.\n\n\r\r");
while (c -> str != 0) {
if (c -> exp != 0) {
if (!wiz) {
if (*c -> exp != '#')
print ("\r\n%s", c -> exp);
}
else {
if (*c -> exp == '#')
print ("\r\n%s:\t\t%s", c -> str, c -> exp);
}
}
c++;
}
more ();
}
error () {
say ("Sorry sir, but I don't understand you!!");
curse_map (curpln);
}
/*
* This function terminates the game. If it is calles with
* a winner, the principal facts of the game will be recorded
* on the galaxy score file. If there is no winner, the game
* will just end gracefully.
*/
# include "score.h"
endgame (mode)
int mode;
{
int resf;
char *ctime ();
struct score sc;
time_t time ();
/* force the printout of games played -null */
if (nulluser && !iswiz[1])
mode = 1;
if (mode == -1)
goto noscore;
resf = open (GALSCOR, 1);
if (resf == -1)
goto noscore;
(void) lseek (resf, 0L, 2);
if (mode) {
strcpy (sc.win, ply1), strcpy (sc.los, ply0);
}
else {
strcpy (sc.win, ply0), strcpy (sc.los, ply1);
}
sc.played_at = time (0);
sc.years = year;
(void) write (resf, (char *) & sc, sizeof (sc));
(void) close (resf);
noscore:
term0 ();
doend (mode);
term1 ();
doend (mode);
if (mode != -1)
sleep (7);
(void) kill (0, 9);
}
doend (mode) {
static char *argv[] = {
"IGNORED",
"-t"
};
clear ();
if (mode != -1) {
glxscore (2, argv);
}
ctrlreset ();
(void) fflush (tty);
}
/* check if the capital was invaded */
check_end () {
int j = capitals[0] -> whos;
if (j == capitals[1] -> whos)
end_game (j);
}
/*
* A suicidal command. When all is lost.
*/
give_up () {
end_game (!player);
}
/*
* This function enables two players to discontinue the game
* withourt any of them loosing face. Of course, they both
* must agree.
*/
quit () {
if (wants_quit[player]) {
wants_quit[player] = 0;
say ("Canceling last quit request.");
return;
}
if (!wants_quit[!player]) {
wants_quit[player] = 1;
say ("Waiting for him to agree....");
dowrite_enemy ("I would like to quit. If offer accepted, give the \"qt\" command.", !player);
return;
}
endgame (-1);
}
pversion () {
extern char version[80];
say (version);
}
/* STOP the time */
no_new () {
if (nulluser || iswiz[player] == 1) {
no_new_year = 1;
return;
}
/* We want to have a break! */
if (wants_pause[player]) {
say ("Cancelling last pause request");
wants_pause[player] = 0;
return;
}
wants_pause[player] = 1;
if (wants_pause[!player]) {
Pause = 1;
no_new_year = 1;
dowrite_enemy ("Break activated, Sir!!!", player);
dowrite_enemy ("Break activated, Sir!!!", !player);
return;
}
say ("Waiting for him to agree.....");
dowrite_enemy ("Hey, let's take a break OK ?", !player);
}
/*
* If the two players ask for a new year - so it will happen.
* wizard may force one.
*/
next_year () {
if (nulluser || iswiz[player] == 1) {
no_new_year = 0;
Pause = 0;
softclock (1);
return;
}
if (wants_newy[player]) {
wants_newy[player] = 0;
if (Pause)
dowrite_enemy ("Sorry. I still need time.", !player);
say ("Canceling last new_year request.");
return;
}
if (!wants_newy[!player]) {
wants_newy[player] = 1;
if (Pause) {
dowrite_enemy ("Let's continue the game O.K. ?", !player);
say ("Waiting for him to agree...");
}
return;
}
wants_newy[player] = 0;
wants_newy[!player] = 0;
no_new_year = 0;
if (Pause) {
Pause = 0;
dowrite_enemy ("There we go again!!", player);
dowrite_enemy ("There we go again!!", !player);
softclock (2);
return;
}
softclock (1);
}
SHAR_EOF
if test 16496 -ne "`wc -c parse.c`"
then
echo shar: error transmitting parse.c '(should have been 16496 characters)'
fi
# End of shell archive
exit 0
--
Erik Bailey -- 7 Oak Knoll (USENET courtesy of
ihnp4!think!ejb Arlington, MA 02174 Thinking Machines Corp.
ejb@think.com (617) 643-0732 Cambridge, MA)
It takes thought to make a program that thinks.
But it takes work to make a program that works.