|
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: 21037 (0x522d) Types: TextFile Names: »move_to.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Galaxy/src/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); }