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.