[comp.sources.misc] v07i080: Whales and Plankton, part 07/13

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (07/19/89)

Posting-number: Volume 7, Issue 80
Submitted-by: loy@gtx.UUCP (Bob Loy)
Archive-name: whpl/part07

# whpl07of13.shar
#---cut here---cut here---cut here---cut here---cut here---
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files.
# This archive created: Sat Jan 14 04:04:43 MST 1989
export PATH; PATH=/bin:$PATH
echo shar: extracting "'whx.c2'" '(29028 characters)'
if test -f 'whx.c2'
then
	echo shar: will not over-write existing file "'whx.c2'"
else
sed 's/^X//' << \SHAR_EOF > 'whx.c2'
X
X/*---------------------------------------------------------------------------*
X@^
X@@^ void  interim() - Handles interim file output during long runs.  Likely to
X@@^              be called under the -y cmnd line opt, or if NUMWH is high.
X@   output:  global chappend[0], filename append character, is incremented
X@            global chapend[0], filename append character, may be incremented
X@   caller:  main()
X@   calls :  lastuff(), fileout(), countwhales(); malloc(), free(),
X@               may call finish()
X@^  proc  :  Outputs interim whale & stat files, and then reallocates the
X@^              whale structures of the still living whales
X@ 
X@^  Note  :  The internal numbering of the whales also gets changed as they
X@^              are reallocated into a smaller space.
X@
X@*---------------------------------------------------------------------------*/
X 
Xvoid
Xinterim()
X{
X  register  int     j, k = 0;
X  whale_type   *newhales;
X
X  lastuff(1);
X  fileout(1);
X  if (debug >= 5)
X      fprintf(stderr, "\n  CONTINUING -- FILES OUTPUT\n");
X  if (debug >= 6)
X      fprintf(stdout, "\n  CONTINUING -- FILES OUTPUT\n");
X      /* Now create the next interim filename append of two extra chars
X         from "aa" all the way to "zz", if necessary */
X  chappend[0]++;
X  if (chappend[0] == '{')   /* Oops, stepped past the ascii 'z'  } */
X    {
X      chappend[0] = 'a';
X      chapend[0]++;
X      if (chapend[0] == '{')   /* Oops, stepped past the ascii 'z'  } */
X        {
X          finish(1);
X        }
X    }
X  countwhales();
X  if(truwh != malwh + femwh)
X    {
X      if (debug >= 2)
X          fprintf(stderr, "interim(): truwh != malwh + femwh; %4d != %4d\n",
X                  truwh, malwh + femwh);
X      truwh = malwh + femwh;
X    }
X      /* Create room for live whales only */
X  newhales = (whale_type *) malloc(truwh * whale_size);
X  if (newhales == NULL)
X    {
X      if (debug >= 2)
X          fprintf(stderr, "\ninterim(): whale malloc problems.\n");
X      finish(7);
X    }
X      /* Do any resets and assign only live whales to a new array */
X  for (j = 0; j < numwh; j++)
X    {
X      if (whale[j].energy > 9999)
X        {
X              /* Now that the files have been output, we want to clear the
X                 most recent internal arrays that were used for printing */
X          whale[j].endex--;   /* 'cleared' just by dropping the index */
X              /* endex should also track the array of success structures: */
X          whale[j].comp[whale[j].endex].diff = 0;
X          whale[j].comp[whale[j].endex].totl = 0;
X          whale[j].comp[whale[j].endex].rank = 0;
X          if (k >= truwh)
X            {
X              if (debug >= 2)
X                  fprintf(stderr,
X                          "\ninterim(): truwh >= new whale array size.\n");
X              free((char*) newhales);
X              finish(6);
X            }
X          newhales[k] = whale[j];
X          k++;
X        }
X    }
X      /* Close and reassign pointer to whale array */
X  free((char*) whale);
X  whale = newhales;
X  numwh = truwh;
X  if (debug >= 5)
X      fprintf(stderr, "\n  numwh being reset to: %d.\n\n", numwh);
X  if (debug >= 6)
X      fprintf(stdout, "\n  numwh being reset to: %d.\n\n", numwh);
X}
X
X/*---------------------------------------------------------------------------*
X@
X@@  int   plankcall() - Calling function for ongoing plankton regeneration.
X@   input :  global variable regrow
X@   output:  plankton may be regrown in locarr[] if population is below the
X@               lower floor limit
X@   caller:  movewhale()
X@   calls :  plankgrow(), countplank(), printscreen()
X@
X@*---------------------------------------------------------------------------*/
X
Xint
Xplankcall()
X{
X  int     plank;
X
X  plank = countplank();
X  if (plank < regrow)
X    {
X      printscreen();
X      if (debug >= 7)
X          fprintf(stdout, "      plank   =   %d\n", plank);
X      plankgrow(2);
X      plankgrow(1);
X          /*  one possible use of stopgrow: ----
X      while (plank < stopgrow)
X        {
X          plankgrow(2);
X          plankgrow(1);
X          plank = countplank();
X        } --------------------------------------*/
X      plank = countplank();
X      if (debug >= 7)
X          fprintf(stdout, "      plank   =   %d\n", plank);
X      printscreen();
X      return(1);
X    }
X  return(0);
X}
X
X/*---------------------------------------------------------------------------*
X@
X@@  void  movewhale(one) - Moves whales based on individual genes fired.  See
X@@              also comments in genes.c: at top of file, and in genesets()
X@   input :  Whole whale list, mvwhle[] & locarr[] arrays
X@   output:  .energy field changes & location changes for individual whales
X@            Plankton removed from locarr[]
X@   caller:  look(), main()
X@   calls :  nextrand(), genesets(), boundstest(), plankcall();
X@               malloc(),  may call finish();  may call exit()
X@   proc  :  First, an overview of the loops in this function:
X@            (1) For the number of move turns this month
X@               (2) For each (live) whale
X@                  (3) While this whale still has room to store moves
X@                     If whale is in hunt or feed mode?
X@                     Hunt mode:
X@                     (4) For each gene in a (randomly picked) chromosome
X@                        (5) For all the moves that gene stores in mvwhle[],
X@                              transfer them to proper place in moves[],
X@                              and update the whale's location in locarr[].
X@                     Feed mode:
X@                     (4)(5), Same basic For-loops
X@            Then, a look at what can cause breaks from the loops:
X@                        (5) Constant BRKGENE = 1 will force break in middle
X@                               of gene as soon as whale[wich].huntfeed
X@                               changes state, otherwise gene 'finishes'
X@                            Chngemode is incremented upon .huntfeed change
X@                     (4) Variable chngemode > 0 will force break in middle
X@                            of chromosome loop
X@                         While-loop test is also specifically tested at
X@                            this level as well; break is propagated thru
X@                            level (3) by variable "endturn"
X@                 (3) While-loop test is to make sure each whale's section
X@                         of the moves[] array isn't overwritten when
X@                         constant NORMAL = 1
X@                     If constant NORMAL = 0, only one chromosome per
X@                        whale per move will fire (otherwise all whale
X@                        moves, regardless of genetypes of whales, will
X@                        'normalize' to the maximum .hgperchr or .fgperchr
X@                        of all the whales in the run), so loop is broken
X@               (2) End of loop (3) propagates through this level
X@            (1) Counts through constant MVGRP for number of whale turns this
X@                   'month' (Do-loop with "months" switch statement in main()
X@                   can be considered loop level (0)).
X@
X@   Note  :  All whales get a chance to hunt/feed, then plankton are erased
X@
X@*---------------------------------------------------------------------------*/
X
Xvoid
Xmovewhale()
X{
X  register  int     h, j, test;
X  register  int     wich;
X  int     e, k, n;
X  int    *moves;
X  int     movesdex;
X  short   chromo;
X  short   totmvs;
X  short   maxtotmv;
X  short   chngemode;
X  short   endturn;
X  int     f = 0;
X  int     mvgroup = MVGRP;
X
X      /* Size the maximum number of location changes */
X  maxtotmv = MAX(hgpcflg * MAXGMV, fgpcflg * MAXGMV);
X      /* Allocate space for storage of location changes */
X  moves = (int*) malloc(numwh * maxtotmv * MAXGMV * (sizeof(int)));
X  if (moves == NULL)
X    {
X      if (debug >= 2)
X          fprintf(stderr, "\nMoves malloc problems.\n");
X      finish(8);
X    }
X      /* Initialize array */
X  for (j = 0; j < numwh * maxtotmv * MAXGMV; j++)
X      moves[j] = -1;
X      /* Start moving */
X  for (k = 0; k < mvgroup; k++)
X    {
X          /* For each whale */
X      for (wich = 0; wich < numwh; wich++)
X        {
X          totmvs = 0;
X          chngemode = 0;
X          endturn = 0;
X              /* Find this whale's section of moves[] */
X          movesdex = wich * maxtotmv * MAXGMV;
X              /* If whale is alive */
X          if (whale[wich].energy > 9999)
X            {
X                  /* While whale's moves are less than there is space for */
X              while (totmvs < maxtotmv)
X                {
X                      /* Is it hunting or feeding? */
X                  if (whale[wich].huntfeed == 'H')
X                    {
X                          /* Pick a chromosome to fire */
X                      switch(whale[wich].hgperchr - '0')
X                        {
X                          case  0:
X                              chromo = 0;
X                              randflg = TRUE;
X                              whale[wich].hgperchr += (Uchar) hgpcflg;
X                              break;
X                          case  1:
X                              chromo = nextrand() & 0xF;
X                              break;
X                          case  2:
X                              chromo = nextrand() & 0xE;
X                              break;
X                          case  4:
X                              chromo = nextrand() & 0xC;
X                              break;
X                          case  8:
X                              chromo = nextrand() & 0x8;
X                              break;
X                          case 16:
X                              chromo = 0;
X                              break;
X                          default:
X                              if (debug >= 2)
X                                {
X                                  fprintf(stderr,
X                                          "whale[%d].hgperchr = %d,\n",
X                                          wich, whale[wich].hgperchr - '0');
X                                  fprintf(stderr, "  must divide into 16\n");
X                                }
X                              exit(22);
X                        }
X                          /* For each gene in the chromosome */
X                      for (j = 0; j < whale[wich].hgperchr - '0'; j++)
X                        {
X                          whale[wich].huntdex = chromo + j;
X                          genesets(wich);
X                          if (totmvs + mvwhle[0] > maxtotmv)
X                            {
X                              endturn++;
X                              break;
X                            }
X                          test = whale[wich].locatn;
X                              /* For each move mapped by the gene */
X                          for (h = 1; h <= mvwhle[0]; h++)
X                            {
X                                  /* Hopefully, this test saves some time */
X                              if ((test <= MAXGMV * vbias) ||
X                                      (test >= area - MAXGMV * vbias))
X                                {
X                                  n = mvwhle[h];
X                                  n = boundstest(n);
X                                  mvwhle[h] = n;
X                                }
X                                  /* Assign moves and increment move count */
X                              moves[movesdex + (totmvs)] = mvwhle[h];
X                              whale[wich].locatn = mvwhle[h];
X                              totmvs++;
X                                  /* Found plankton?... */
X                              if (locarr[whale[wich].locatn] == '.')
X                                {
X                                  whale[wich].energy += PLUS;
X                                  whale[wich].lastfed = 0;
X                                  chngemode++;
X                                  if (BRKGENE)
X                                      break;
X                                }
X                              else   /* ...or not */
X                                {
X                                  whale[wich].energy -= MINUS;
X                                  whale[wich].lastfed++;
X                                }
X                            }
X                          if (chngemode)   /* Change from hunt to feed */
X                            {
X                              if (whale[wich].lastfed < COUNTVAL)
X                                  whale[wich].huntfeed = 'F';
X                              chngemode = 0;
X                              break;
X                            }
X                        }
X                      if (randflg)   /* Do resets */
X                        {
X                          whale[wich].hgperchr = '0';
X                          randflg = FALSE;
X                        }
X                      if (!NORMAL)
X                          break;
X                      if (endturn)
X                          break;
X                    }
X                  else if (whale[wich].huntfeed == 'F')
X                    {
X                          /* Pick a chromosome to fire */
X                      switch(whale[wich].fgperchr - '0')
X                        {
X                          case  0:
X                              chromo = 0;
X                              randflg = TRUE;
X                              whale[wich].fgperchr += (Uchar) fgpcflg;
X                              break;
X                          case  1:
X                              chromo = nextrand() & 0xF;
X                              break;
X                          case  2:
X                              chromo = nextrand() & 0xE;
X                              break;
X                          case  4:
X                              chromo = nextrand() & 0xC;
X                              break;
X                          case  8:
X                              chromo = nextrand() & 0x8;
X                              break;
X                          case 16:
X                              chromo = 0;
X                              break;
X                          default:
X                              if (debug >= 2)
X                                {
X                                  fprintf(stderr,
X                                          "whale[%d].fgperchr = %d,\n",
X                                          wich, whale[wich].fgperchr - '0');
X                                  fprintf(stderr, "  must divide into 16\n");
X                                }
X                              exit(22);
X                        }
X                          /* For each gene in the chromosome */
X                      for (j = 0; j < whale[wich].fgperchr - '0'; j++)
X                        {
X                          whale[wich].feeddex = chromo + j;
X                          genesets(wich);
X                          if (totmvs + mvwhle[0] > maxtotmv)
X                            {
X                              endturn++;
X                              break;
X                            }
X                          test = whale[wich].locatn;
X                              /* For each move mapped by the gene */
X                          for (h = 1; h <= mvwhle[0]; h++)
X                            {
X                                  /* Hopefully, this test saves some time */
X                              if ((test <= MAXGMV * vbias) ||
X                                      (test >= area - MAXGMV * vbias))
X                                {
X                                  n = mvwhle[h];
X                                  n = boundstest(n);
X                                  mvwhle[h] = n;
X                                }
X                                  /* Assign moves and increment move count */
X                              moves[movesdex + (totmvs)] = mvwhle[h];
X                              whale[wich].locatn = mvwhle[h];
X                              totmvs++;
X                                  /* Found plankton?... */
X                              if (locarr[whale[wich].locatn] == '.')
X                                {
X                                  whale[wich].energy += PLUS;
X                                  whale[wich].lastfed = 0;
X                                }
X                              else   /* ...or not */
X                                {
X                                  whale[wich].energy -= MINUS;
X                                  whale[wich].lastfed++;
X                                  if (whale[wich].lastfed >= COUNTVAL)
X                                    {
X                                      chngemode++;
X                                      if (BRKGENE)
X                                          break;
X                                    }
X                                }
X                            }
X                          if (chngemode)   /* Change from feed to hunt */
X                            {
X                              if (whale[wich].lastfed >= COUNTVAL)
X                                  whale[wich].huntfeed = 'H';
X                              chngemode = 0;
X                              break;
X                            }
X                        }
X                      if (randflg)   /* Do resets */
X                        {
X                          whale[wich].fgperchr = '0';
X                          randflg = FALSE;
X                        }
X                      if (!NORMAL)
X                          break;
X                      if (endturn)
X                          break;
X                    }
X                  else
X                    {
X                      if (debug >= 2)
X                          fprintf(stderr,
X                                "movewhale(): whale[].huntfeed != H or F\n");
X                      exit(22);
X                    }
X                }
X            }
X        }
X          /* Find all the moves (locations) in moves[] and remove plankton */
X              /* in locarr[] at those locations */
X      for (j = 0; j < numwh * maxtotmv * MAXGMV; j++)
X        {
X          if (moves[j] >= 0)
X              locarr[moves[j]] = ' ';
X        }
X          /* The following three if()'s playing with variables e & f are to */
X              /* get around the times the % operator yields a result of 0 */
X              /* twice or more in a row due to rounding */
X      if ((k + 1) % (mvgroup / truwh) == 0)
X        {
X          e = k + 10;
X          f++;
X        }
X      if ((f == 1) && (k > 0))
X        {
X          if (debug >= 7)
X              fprintf(stdout, "  Move %5d\n", k);
X          if (debug >= 9)
X            {
X              fprintf(stdout, "  hunt moves  =  %ld\n", aiches);
X              fprintf(stdout, "  feed moves  =  %ld\n", effs);
X            }
X          if (debug >= 9)
X              for (j = 0; j < numwh; j++)
X                  fprintf(stdout, "Whale %3d  has %8d energy.\n",
X                          j, whale[j].energy);
X              /* Test for low plankton population & regrow, if necessary */
X          j = plankcall();
X          if (j)   /* Re-initialize array of location changes */
X            {
X              for (j = 0; j < numwh * maxtotmv * MAXGMV; j++)
X                  moves[j] = -1;
X            }
X          f++;
X        }
X      if ((k == e) || ((k + 1) == mvgroup))
X          f = 0;
X    }
X  if (debug >= 7)
X      fprintf(stdout, "    Move %5d\n", k);
X  if (debug >= 9)
X      for (wich = 0; wich < numwh; wich++)
X          fprintf(stdout, "    Whale %3d  has %8d energy.\n",
X                  wich, whale[wich].energy);
X  free((char *) moves);
X}
X
X/*---------------------------------------------------------------------------*
X@
X@@  void  main(argc, argv) - Calling function for whpl.c and associated files.
X@   input :  Constants from whpl.h and command line arguments.
X@   output:  Most output comes from other functions called directly or indir-
X@               ectly from here, including finish(), which handles most of the
X@               program's file output.
X@   calls :  ophandle(), randinit(), whaleinit(), finish(), countwhales(),
X@               clearlocarr(), plankplace(), countplank(), printscreen(),
X@               plankgrow(), movewhale(), whaleplace(), whaledie(), interim(),
X@               look(), mate()
X@   proc  :  There are three basic sections to this function:
X@            First, the whales are initialized, either randomly, or by a read
X@               from a whale file (call to whaleinit).  Command line opts
X@               heavily condition how these two sources of whales are combined.
X@            Second, other initializations take place, including the plankton,
X@               which are then grown into their normal population range.
X@            Finally comes the main program loops which control the timing of
X@               the ecology's overall events; hunting, eating, mating, dying.
X@
X@   Note  :  The variables "months" and "year" do not have the chronological
X@               meaning normally associated with them on Earth.  Months is
X@               the loop variable and switch value used in the main control
X@               do-loop, while year is normally incremented when mate() is
X@               called, and used in computations involving the "age" of speci-
X@               fic whales.  "cycle", incremented once each time through the
X@               main control do-loop, cooresponds better to our earthly notion
X@               of a year.  The "MONTHS" constant in whpl.h sets the number of
X@               months per cycle.
X@            In the version 1.10 release of this function, one cycle equals
X@               5 years.  This can have an unexpected effect on the -y option,
X@               e.g., using -y6 on the command line will actually create 10
X@               generations of whales, rather than 6, due to this granularity.
X@               If you modify the do-loop to call mate() only once, then one
X@               cycle will equal one year.
X@
X@   Note  :  Variable "dielim" is changed dynamically in the present (whpl.c
X@               v1.10) release version of this function.  This variable has
X@               the most effect of any as far as keeping the whale population
X@               steady.  Setting it to 2 for two mate cycles and to 1 for
X@               three seems to do reasonably well.  When, (in relation to
X@               mate()), and how often, whaledie() is called also has an
X@               effect on whether whales generaly increase or decrease.
X@
X@*---------------------------------------------------------------------------*/
X
Xvoid
Xmain(argc, argv)
X  int    argc;
X  char   *argv[];
X{
X  static  int     months;
X  int     j = FNMTRUNC - 1;
X  char    datr[11];
X  char    temp[11];
X  Uint    dater;
X  int     plank;
X  short   pre = 0;
X  short   post = 0;
X  short   cycle = 0;
X
X      /* Do some simple tests on constants ? */
X
X      /* Get command line args */
X  ophandle(argc, argv);
X      /* Initialize random number generators */
X  randinit();
X      /* Other initializations */
X  regrow = area / 6;
X  stopgrow = area / 3;
X      /* Will we be looking at whale tracks? (Use of -t option restricts
X             locarr[] array size to 288 * 225 pixels) */
X  if(trakflg)
X    {
X      area = 64800;
X      vbias = 225;
X    }
X      /* Initialize location array and scratch array */
X  locarr = (Uchar*) malloc(area);
X  if (locarr == NULL)
X    {
X      if (debug >= 2)
X          fprintf(stderr, "\nlocarr malloc problems.\n\n");
X      exit(8);
X    }
X  secarr = (Uchar*) malloc(area);
X  if (secarr == NULL)
X    {
X      if (debug >= 2)
X          fprintf(stderr, "\nsecarr malloc problems.\n\n");
X      exit(8);
X    }
X      /* Are we just browsing... */
X  if(trakflg)
X    {
X      look();
X      exit(0);
X    }
X      /* ...or running the program? */
X  if (debug >= 5)
X      fprintf(stdout, "\n\n  RUN  %u\n\n", daterun);
X      /* Create archive file name */
X  if (!wharcflg)
X    {
X      dater = daterun / 10000;
X      dater *= 100;
X      sprintf(temp, "%8u", dater);
X      do{
X          j++;
X          datr[j - FNMTRUNC] = temp[j];
X        } while (temp[j] != '\0');
X      strcat(wharcfile, "wha");
X      strcat(wharcfile, datr);
X    }
X      /* Initialize whales */
X  whaleinit();
X  countwhales();
X      /* We've initialized the whales, now let's init the plankton: */
X  clearlocarr();
X  plankplace(1, 0);
X  plank = countplank();
X  if (debug >= 5)
X      fprintf(stdout, "  Seeded plankton          = %7d\n", plank);
X  printscreen();
X  for (j = 0; j < 4; j++)
X      plankgrow(1);
X  plank = countplank();
X  if (debug >= 7)
X      fprintf(stdout, "  Interim plankton         = %7d\n", plank);
X  printscreen();
X  plankgrow(2);
X  plankgrow(1);
X  plank = countplank();
X  if (debug >= 5)
X      fprintf(stdout, "  Final initial plankton   = %7d\n\n", plank);
X  printscreen();
X      /* One finial initialization step; tune Wa-Tor to this set of whales: */
X  pre = 6;  /* <-- Remove this line to bypass the "pre" loop altogether */
X  if (pre)
X    {
X      if (debug >= 5)
X          fprintf(stdout, "Conditioning world for %d months\n", pre);
X      for (months = 1; months <= pre; months++)
X        {
X          movewhale();
X          if (debug >= 5)
X              fprintf(stdout, "    %2d\n", months);
X        }
X      for (j = 0; j < numwh; j++)
X        {
X          whale[j].locatn = whaleplace();
X          whale[j].energy = 1000000;
X          whale[j].lastfed = 1000000;
X        }
X    }
X      /* Now to get into the run for real: */
X  dielim = 1;  /* Set here just to make sure it's set to a reasonable value */
X  do{
X      cycle++;  /* Number of times through the do-loop */
X          /* Count up through the 'months' from 1, THRU the value of MONTHS */
X      for (months = 1; months <= MONTHS; months++)
X        {
X          if (debug >= 7)
X              fprintf(stdout, "\nCycle %d,  Month %d\n", cycle, months);
X          if (debug >= 7)
X              fprintf(stdout, "  Year %d\n", year);
X          switch(months)  /* So what do we do with each new 'month'? */
X            {
X              case  1:
X                  dielim = 2;   /* <-- Whale population tends to increase */
X                  movewhale();
X                  break;
X              case 13:
X                  dielim = 1;   /* <-- Whale population tends to decrease */
X                  movewhale();
X                  break;
X              case  6:
X              case 12:
X              case 18:
X              case 24:
X              case 30:
X                      /* Be somewhat careful about changing the order of these
X                           statements.  Nothing is likely to break, but output
X                           based on year value may not be so meaningful: check
X                           the functions themselves.  Also, it's safest to
X                           call interim() before mate() to help keep within
X                           the maximum allowable number of whales  */
X                  year++;
X                  movewhale();
X                  whaledie(1);
X                      /* Save whales to file & reallocate live ones */
X                  if (numwh > interlim) /* default limit about 3/5 of MAXWH */
X                      interim();
X                  mate();
X                  break;
X              default:   /* <-- All cases not specifically numbered above */
X                  movewhale();  /* This, then, gets called every month */
X                  break;
X            }
X        }
X      if (debug >= 7)
X          fprintf(stdout, "Cycle %d,  Month %d\n", cycle, months);
X      if (debug >= 7)
X          fprintf(stdout, "  Year %d\n", year);
X          /* Should't remove this!  Modify SAFETY in whpl.h, if necessary: */
X      if (cycle >= SAFETY)
X        {
X          if (debug >= 2)
X              fprintf(stderr,
X                      "\nmain():  EXIT FROM MAIN LOOP:  cycle > SAFETY\n\n");
X          if (debug >= 6)
X              fprintf(stdout,
X                      "\nmain():  EXIT FROM MAIN LOOP:  cycle > SAFETY\n\n");
X          break;
X        }
X      if (year >= yearflg)
X        {
X          break;                      /* <-- NORMAL EXIT FROM MAIN DO LOOP */
X        }
X    } while (1);  /* do-loop continues */
X      /* Run whales some more to get their final energy rankings: */
X  post = 12;  /* <-- Remove this line to bypass the "post" loop altogether */
X  if (post)
X    {
X      if (debug >= 5)
X          fprintf(stdout, "Final whale moves for %d months\n", post);
X      for (months = 1; months <= post; months++)
X        {
X          movewhale();
X          if (months == 3 || months == 7)
X            {
X              for (j = 0; j < numwh; j++)
X                {
X                  whale[j].locatn = whaleplace();
X                  whale[j].lastfed = 1000000;
X                }
X            }
X          if (debug >= 5)
X              if (!(months % 2))
X                  fprintf(stdout, "    %2d\n", months);
X        }
X    }
X  if (debug >= 5)
X      fprintf(stdout, "main():  finishing run\n");
X  if (debug >= 6)
X      fprintf(stderr, "main():  finishing run\n");
X      /* I prefer to trim the whales' numbers one last time */
X  whaledie(0);
X      /* Final computations and file output */
X  finish(1);
X}
SHAR_EOF
if test 29028 -ne "`wc -c < 'whx.c2'`"
then
	echo shar: error transmitting "'whx.c2'" '(should have been 29028 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0
---

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                |
             Bob Loy            |     Life is the detour you take on the
    ...!sun!sunburn!gtx!loy     |     way to where you're really going.
                                |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~