[comp.sources.misc] v07i082: Whales and Plankton, part 09/13

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

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

# whpl09of13.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:56 MST 1989
export PATH; PATH=/bin:$PATH
echo shar: extracting "'whpl.c3'" '(29390 characters)'
if test -f 'whpl.c3'
then
	echo shar: will not over-write existing file "'whpl.c3'"
else
sed 's/^X//' << \SHAR_EOF > 'whpl.c3'
X
X/*---------------------------------------------------------------------------*
X@
X@@  int   allsort() - Returns energy level of lowest quartile of whales.
X@   return:  Energy value of weakest whale to still keep alive
X@               (approximately lowest 1/4 die)
X@   caller:  whaledie()
X@   calls :  qhilo(); qsort(), calloc(),  may call finish()
X@
X@*---------------------------------------------------------------------------*/
X 
Xint
Xallsort()
X{
X  register  int     j, k;
X  int    *enersort;
X 
X      /* Make space for sort array */
X  enersort = (int*) calloc((truwh), (sizeof(int)));
X  if (enersort == NULL)
X    {
X      if (debug >= 2)
X          fprintf(stderr, "\nallsort(): enersort calloc problems.\n");
X      finish(8);
X    }
X  k = 0;
X      /* Load sort array with live whales */
X  for (j = 0; j < numwh; j++)
X    {
X      if (whale[j].energy > 9999)
X        {
X          enersort[k] = whale[j].energy;
X          k++;
X        }
X    }
X  if (k != truwh)
X    {
X      if (debug >= 2)
X          fprintf(stderr, "\nallsort(): enersort != truwh) %d, %d\n",
X                  k, truwh);
X      if (debug >= 6)
X          fprintf(stdout, "\nallsort(): enersort != truwh) %d, %d\n",
X                  k, truwh);
X    }
X      /* Sort the whales from highest to lowest */
X  qsort((char*)enersort, (k), sizeof(int), qhilo);
X      /* Do wierd algorithm to get the lowest quartile (hey, it works) */
X  k++;
X  k /= 2;
X  j = k / 2;
X  k += j;
X  k--;
X  j = enersort[k];
X  free((char*) enersort);
X  return(j);
X}
X 
X/*---------------------------------------------------------------------------*
X@
X@@  void  whaledie(when) - Kills off less successful whales.
X@   input :  Input parameter fudges years variable, so that years in whale
X@               .energy fields in output files don't overlap (yes, ugly)
X@            Whole whale list
X@   output:  Puts year value into whale.energy field.  This effectively kills
X@               the whale, as energy < 10000 = dead
X@            Resets truwh if any whales die
X@   caller:  main()
X@   calls :  allsort(), countwhales()
X@   proc  :  Increments whale.die field, and then tests against dielim;
X@               won't fire at all if less than 4 whales are still living
X@
X@*---------------------------------------------------------------------------*/
X 
Xvoid
Xwhaledie(when)
X  short   when;
X{
X  register  int     j;
X  int     enerquar;
X  int     dead = 0;
X 
X  if (truwh > 3)
X    {
X      enerquar = allsort();
X      if (debug >= 6)
X          fprintf(stderr, "whaledie():  enerquar = %7d\n", enerquar);
X      if (debug >= 5)
X          fprintf(stdout, "whaledie():  enerquar = %7d\n", enerquar);
X      for (j = 0; j < numwh; j++)
X        {
X              /* "Random" whales don't ever die */
X          if (whale[j].hgperchr == '0' || whale[j].fgperchr == '0')
X              continue;
X          if (whale[j].energy > 9999 && whale[j].energy < enerquar)
X            {
X              whale[j].die++;
X              if (debug >= 9)
X                  fprintf(stderr, "whale[%d].die = %hd\n", j, whale[j].die);
X              if (whale[j].die >= dielim)
X                {
X                  if (debug >= 9)
X                      fprintf(stderr, "whale[%d] dies here\n", j);
X                  whale[j].energy = year - when;
X                  dead++;
X                }
X            }
X        }
X      truwh -= dead;
X    }
X  countwhales();
X}
X
X/*---------------------------------------------------------------------------*
X@
X@@  void  enersave(male whale, save array, set) - Selects male whale for
X@@              individual female whale to mate with.
X@   input :  Each live male whale near to the female, up to MALIM males
X@               Male locations have previously been stored in secarr[]
X@   output:  The number(s) of the male whales with the highest energy, in
X@               the savewh[] array
X@   caller:  attract()
X@   calls :  may call finish()
X@   proc  :  May be called in an initialization mode if "set" parameter > 0,
X@               otherwise compares and saves the best male whale, or whales,
X@               if there is a tie for first
X@                  (ver 1.10: tie whale presently ignored, poor fellow)
X@
X@*---------------------------------------------------------------------------*/
X
Xvoid 
Xenersave(mw, savewh, set)
X  int     mw;
X  int    *savewh;
X  short   set;
X{
X  static  int     j, k;
X
X  if (set)
X    {
X      k = 9999;
X      for(j = 0; j < MALIM + 2; j++)
X          savewh[j] = 0;
X      j = 0;
X    }
X  else
X    {
X      if (k < whale[mw].energy)
X        {
X          k = whale[mw].energy;
X              /* maybe surround by debug level?  Bug seems to be fixed -----*/
X          if (k < 10000)
X              finish(10);
X          j = 0;
X          savewh[j] = mw;
X        }
X          /*  tie whale is saved, but presently ignored */
X      else if (k == whale[mw].energy)
X        { 
X          j++; 
X          if (j > MALIM + 2)
X              j = MALIM + 2;
X          savewh[j] = mw;
X        }
X    }
X}
X
X/*---------------------------------------------------------------------------*
X@
X@@  int   femsort() - Returns energy level of top half of live female whales.
X@   return:  Energy value of weakest female whale to still use for mating
X@               (top half, or top half+1, mate each time)
X@   caller:  mate()
X@   calls :  qhilo(); qsort(), calloc(),  may call finish()
X@
X@*---------------------------------------------------------------------------*/
X
Xint
Xfemsort()
X{
X  register  int     j, k;
X  int    *enersort;
X
X      /* Make space for sort array */
X  enersort = (int*) calloc((femwh), (sizeof(int)));
X  if (enersort == NULL)
X    {
X      if (debug >= 2)
X          fprintf(stderr, "\nfemsort(): enersort calloc problems.\n");
X      finish(8);
X    }
X  k = 0;
X      /* Load sort array with live female whales */
X  for (j = 0; j < numwh; j++)
X    {
X      if (whale[j].sex == 'F' && whale[j].energy > 9999)
X        {
X          enersort[k] = whale[j].energy;
X          k++;
X        } 
X    }
X  if (k != femwh)
X    {
X      if (debug >= 2)
X          fprintf(stderr, "\nfemsort(): enersort != femwh) %d, %d\n",
X                  k, femwh);
X      if (debug >= 6)
X          fprintf(stdout, "\nfemsort(): enersort != femwh) %d, %d\n",
X                  k, femwh);
X    }
X      /* Sort the females from highest to lowest */
X  qsort((char*)enersort, (k), sizeof(int), qhilo);
X      /* Return the median energy value */
X  k--;
X  k /= 2;
X  j = enersort[k];
X  free((char *) enersort);
X  return(j);
X}
X
X/*---------------------------------------------------------------------------*
X@
X@@  int   collision(where) - Assigns each mateable male whale a unique place.
X@   return:  Unique location in secarr[]
X@   caller:  mate(),  may be called by collision() {itself}
X@   calls :  nextrand(), boundstest(),  may call collision() {itself}
X@   proc  :  Keeps calling itself until collisions are resolved or until
X@               global "collisions" variable is incremented way too far
X@
X@*---------------------------------------------------------------------------*/
X
Xint
Xcollision(loc)
X  int     loc;
X{
X  short   tiny;
X
X  collisions++;
X  if (collisions > 100)
X       return(-1);
X  tiny = nextrand() & 0x2;
X  switch(tiny)
X    {
X      case 0 :
X          loc -= HBIAS;
X          break;
X      case 1 :
X          loc -= vbias;
X          break;
X      case 2 :
X          loc += HBIAS;
X          break;
X      case 3 :
X          loc += vbias;
X          break;
X      default:
X          if (debug >= 2)
X              fprintf(stderr, "\n  collision():  case:  default\n");
X          break;
X    }
X  loc = boundstest(loc);
X  if (secarr[loc] != MAXWH + 1)
X      loc = collision(loc);
X  return(loc);
X}
X
X/*---------------------------------------------------------------------------*
X@
X@@  int   attract(female whale) - Function finds nearest males to mate with.
X@   input :  Female whale, secarr[] (where the males are saved by location)
X@   return:  Best male whale in the neighborhood
X@   caller:  mate()
X@   calls :  enersave(), boundstest()
X@   proc  :  The idea is that female releases "pheromones" which spread over
X@               the surface of Wa-Tor.  If I had it to do over again, I'd
X@               just shoot the search in one direction up or down locarr[]
X@               (call it having the pheromones "drift down the current")
X@               This would be easier, FASTER, and not really any less random.
X@
X@*---------------------------------------------------------------------------*/
X
Xint
Xattract(fem)
X  int     fem;
X{
X  register  int     j, k;
X  int     whle;
X  int     males;
X  int     countm = 0;
X  int     phero = 2;
X  int     savewhle[MALIM + 3];
X
X  enersave(0, savewhle, 1);
X  males = malwh;
X  if (males > MALIM)
X      males = MALIM;
X  k = whale[fem].locatn;
X  if (secarr[k] < MAXWH + 1) 
X    {
X      whle = (int) secarr[k];
X      enersave(whle, savewhle, 0);
X      countm++;
X    }
X  while (countm < males)
X    {
X      k = (k - HBIAS) - vbias;
X      k = boundstest(k);
X      if (countm >= males)
X          break;
X      for (j = 0; j < phero; j++)
X        {
X          k += HBIAS;
X          k = boundstest(k);
X          if (secarr[k] < MAXWH + 1) 
X            {
X              whle = (int) secarr[k];
X              enersave(whle, savewhle, 0);
X              countm++;
X            }
X        }
X      if (countm >= males)
X          break;
X      for (j = 0; j < phero; j++)
X        {
X          k += vbias;
X          k = boundstest(k);
X          if (secarr[k] < MAXWH + 1) 
X            {
X              whle = (int) secarr[k];
X              enersave(whle, savewhle, 0);
X              countm++;
X            }
X        }
X      if (countm >= males)
X          break;
X      for (j = 0; j < phero; j++)
X        {
X          k -= HBIAS;
X          k = boundstest(k);
X          if (secarr[k] < MAXWH + 1) 
X            {
X              whle = (int) secarr[k];
X              enersave(whle, savewhle, 0);
X              countm++;
X            }
X        }
X      if (countm >= males)
X          break;
X      for (j = 0; j < phero; j++)
X        {
X          k -= vbias;
X          k = boundstest(k);
X          if (secarr[k] < MAXWH + 1) 
X            {
X              whle = (int) secarr[k];
X              enersave(whle, savewhle, 0);
X              countm++;
X            }
X        }
X      phero += 2;
X    }
X      /*  tie whales were saved, but presently ignored, poor fellows  */
X  whle = savewhle[0];
X      /*  use as a check ONLY if whale[0] is always set to be female
X  if (whle == 0)
X      abort();
X      -----*/
X  for (k = 0; k < 8; k++)
X      savewhle[k] = 0;
X  return(whle);
X}
X
X/*---------------------------------------------------------------------------*
X@
X@@  void  hgjoin2() - Transfers whole hunt gene set from parent to child.
X@   input :  global noclone used to randomly choose between father or mother
X@   caller:  mate(), hgjoin1()
X@
X@*---------------------------------------------------------------------------*/
X
Xvoid
Xhgjoin2()
X{
X  register  int     j;
X
X  if (noclone % 2)
X    {
X      whale[baby].hunttype = whale[pop].hunttype;
X      whale[baby].hgperchr = whale[pop].hgperchr;
X      for (j = 0; j < 16; j++)
X          whale[baby].huntgene[j] = whale[pop].huntgene[j];
X    }
X  else
X    { 
X      whale[baby].hunttype = whale[mom].hunttype;
X      whale[baby].hgperchr = whale[mom].hgperchr;
X      for (j = 0; j < 16; j++)
X          whale[baby].huntgene[j] = whale[mom].huntgene[j];
X    }
X}
X
X/*---------------------------------------------------------------------------*
X@
X@@  void  hgjoin1() - Randomly transfers hunt chrmosomes from father whale or
X@@              mother whale to child whale.
X@   caller:  mate()
X@   calls :  hgjoin2(), randout()
X@
X@   Note  :  It makes no real sense to call this function unless both parents'
X@               hgperchr values are equal.  Call hgjoin2(), instead.
X@
X@*---------------------------------------------------------------------------*/
X
Xvoid
Xhgjoin1()
X{
X  register  int     j, k;
X  Ushort  tiny;
X  Uchar   inverse;
X  short   chromo;
X
X  if (whale[pop].hgperchr - '0' == 16)
X    {
X      hgjoin2();
X      return;
X    }
X  tiny = (Ushort) randout();
X  if (tiny % 2)
X      whale[baby].hunttype = whale[pop].hunttype;
X  else
X      whale[baby].hunttype = whale[mom].hunttype;
X  whale[baby].hgperchr = whale[pop].hgperchr;
X  inverse = 16 / (whale[pop].hgperchr - '0');
X  chromo = 0;
X  for (j = 0; j < inverse; j++)
X    {
X      tiny = (Ushort) randout();
X      if (tiny % 2)
X        {
X          for (k = 0; k < whale[pop].hgperchr - '0'; k++)
X              whale[baby].huntgene[chromo + k] =
X                      whale[pop].huntgene[chromo + k];
X        }
X      else
X        {
X          for (k = 0; k < whale[pop].hgperchr - '0'; k++)
X              whale[baby].huntgene[chromo + k] =
X                      whale[mom].huntgene[chromo + k];
X        }
X      chromo += whale[pop].hgperchr - '0';
X    }
X}
X
X/*---------------------------------------------------------------------------*
X@
X@@  void  fgjoin2() - Transfers whole feed gene set from parent to child.
X@   input :  constant TOCLONE, global noclone
X@   caller:  mate(), fgjoin1()
X@   calls :  randout()
X@   proc  :  If hgjoin2() is called previous to this function, there is a
X@               definite chance that the baby will be an exact replica of
X@               one of it's parents (this can also happen when mate() calls
X@               hgjoin1() and fgjoin1(), the chromosome-mixing functions, but
X@               the laws of chance with those two funcs keep it a fairly low
X@               probability).  The whpl.h constant TOCLONE conditions the
X@               global noclone to control this duplication problem.  See the
X@               comments within the function, below.
X@
X@*---------------------------------------------------------------------------*/
X
Xvoid
Xfgjoin2()
X{
X  register  int     j;
X
X  if (debug >= 9)
X      fprintf(stdout, "  noclone = %d\n", noclone);
X  if (TOCLONE == 0)                                  /* will not clone */
X      noclone++;
X  else if (TOCLONE == 1)                        /* randomly will clone */
X      noclone = (Ushort) randout();
X  else if (TOCLONE >= 2)                      /* will definitely clone */
X      ;
X  if (noclone % 2)
X    {
X      whale[baby].feedtype = whale[pop].feedtype;
X      whale[baby].fgperchr = whale[pop].fgperchr;
X      for (j = 0; j < 16; j++)
X          whale[baby].feedgene[j] = whale[pop].feedgene[j];
X    }
X  else
X    { 
X      whale[baby].feedtype = whale[mom].feedtype;
X      whale[baby].fgperchr = whale[mom].fgperchr;
X      for (j = 0; j < 16; j++)
X          whale[baby].feedgene[j] = whale[mom].feedgene[j];
X    }
X}
X
X/*---------------------------------------------------------------------------*
X@
X@@  void  fgjoin1() - Randomly transfers feed chrmosomes from father whale or
X@@              mother whale to child whale.
X@   caller:  mate()
X@   calls :  fgjoin2(), randout()
X@
X@   Note  :  It makes no real sense to call this function unless both parents'
X@               fgperchr values are equal.  Call fgjoin2(), instead.
X@
X@*---------------------------------------------------------------------------*/
X
Xvoid
Xfgjoin1()
X{
X  register  int     j, k;
X  Ushort  tiny;
X  Uchar   inverse;
X  short   chromo;
X
X  if (whale[pop].fgperchr - '0' == 16)
X    {
X      fgjoin2();
X      return;
X    }
X  tiny = (Ushort) randout();
X  if (tiny % 2)
X      whale[baby].feedtype = whale[pop].feedtype;
X  else
X      whale[baby].feedtype = whale[mom].feedtype;
X  whale[baby].fgperchr = whale[pop].fgperchr;
X  inverse = 16 / (whale[pop].fgperchr - '0');
X  chromo = 0;
X  for (j = 0; j < inverse; j++)
X    {
X      tiny = (Ushort) randout();
X      if (tiny % 2)
X        {
X          for (k = 0; k < whale[pop].fgperchr - '0'; k++)
X              whale[baby].feedgene[chromo + k] =
X                      whale[pop].feedgene[chromo + k];
X        }
X      else
X        {
X          for (k = 0; k < whale[pop].fgperchr - '0'; k++)
X              whale[baby].feedgene[chromo + k] =
X                      whale[mom].feedgene[chromo + k];
X        }
X      chromo += whale[pop].fgperchr - '0';
X    }
X}
X
X/*---------------------------------------------------------------------------*
X@
X@@  void  mate() - Creation of new unique whales with inherited traits.
X@   input :  Whole whale list; Constants INBREED1, INBREED2, MAXWH
X@   output:  Newly created baby whales
X@            Baby whales added to parents' offspring records
X@   caller:  main()
X@   calls :  loadsecarr(), collision(), femsort(), whaleload(), attract(),
X@               randout(), whaleplace(), countwhales(); realloc(),
X@               hgjoin1(), hgjoin2(), fgjoin1(); fgjoin2(),
X@               may call: kidsout(), finish()
X@   proc  :  See comments in func, lots going on; main job is to allocate
X@               space for new whales and initialize their structure fields,
X@               either with default values (the call to whaleload()), or
X@               by providing for random inheritance of traits from the parent
X@               whales.
X@            Down where the constants INBREEDx take effect, there are comments
X@               just above the case statements such as:  * Good - Fair: *
X@               these refer to "Huntgene match" - "Feedgene match", which is a
X@               comment applicable to runs containing mixed breeds, concerning
X@               just how different the two parents' genesets actually are.
X@               The constant INBREED1 determines, when the parent's hunt/feed
X@               types are different, whether to mix chromosomes, or rather to
X@               pass on one parent's whole geneset (see also notes on TOCLONE
X@               in fgjoin2(), above).
X@                  When the parents' hgperchr &/or fgperchr genes are differ-
X@               ent, it makes even less sense to mix genesets up too much, so
X@               INBREED2 chooses between passing on the whole geneset, or not
X@               even having the whales produce offspring at all.
X@
X@   Note  :  The sets of 16 hunt and feed genes are actually grouped evenly
X@               into CHROMOSOMES, for example, 4 sets of 4 chromosomes each
X@               (depending on whale structure fields .hgperchr and .fgperchr),
X@               and these chromosome bunches are what are actually selected
X@               randomly from the parents.
X@            However, it may or may not make sense to pass on chromosomes if
X@               the parents are of very different breeds; sometimes the
X@               function may pass on the whole hunt- or feed-gene set.
X@
X@*---------------------------------------------------------------------------*/
X
Xvoid
Xmate()
X{
X  register  int     j;
X  Uint    oldwh;
X  int     enermed;
X  Ushort  tiny;
X  int     mateswit;
X  short   nobaby = 0;
X  char    genes[7];
X
X  if (debug >= 6)
X      fprintf(stderr, "mate():  year is %d\n", year);
X  if (debug >= 5)
X      fprintf(stdout, "mate():  year is %d\n", year);
X  if (numwh > MAXWH)
X    {
X      if (debug >= 2)
X        {
X          fprintf(stderr,
X                  "Maximum number of whales (%d) exceeded.  Program\n", MAXWH);
X          fprintf(stderr, "  will proceed, but NO further mating will take\n");
X          fprintf(stderr, "  place until some whales die off.\n");
X        }
X      return;
X    }
X  if (malwh == 0)
X    {
X      if (debug >= 2)
X          fprintf(stderr, "No live males left to mate with\n\n");
X      finish(3);
X    }
X  if (femwh == 0)
X    {
X      if (debug >= 2)
X          fprintf(stderr, "No live females left to mate with\n\n");
X      finish(4);
X    }
X  loadsecarr(MAXWH + 1);     /* Initialize secarr[] with 255 (version 1.10) */
X  for (j = 0; j < numwh; j++)
X    {
X      if (whale[j].sex == 'M' && whale[j].energy > 9999)
X        {
X          if (secarr[whale[j].locatn] == MAXWH + 1)
X              secarr[whale[j].locatn] = (char) j;
X          else if (secarr[whale[j].locatn] < MAXWH + 1)
X            {
X              whale[j].locatn = collision(whale[j].locatn);
X              if (whale[j].locatn < 0)
X                {
X                  if (debug >= 2)
X                    {
X                      fprintf(stderr, "\n  mate():  too many calls to");
X                      fprintf(stderr, " collision()\n\n");
X                    }
X                  finish(5);
X                }
X              collisions = 0;
X              secarr[whale[j].locatn] = (Uchar) j;
X            }
X          else
X              if (debug >= 2)
X                  fprintf(stderr,
X                          "\n  mate():  secarr[value] > %d", MAXWH + 1);
X        }
X    }
X  enermed = femsort();
X  oldwh = numwh;
X  for (mom = 0; mom < oldwh; mom++)
X    {
X      if ((whale[mom].sex == 'F') && (whale[mom].energy >= enermed))
X          numwh++;
X    }
X  whale = (whale_type *) realloc((char *) whale, (numwh * whale_size));
X  if (whale == NULL)
X    {
X      if (debug >= 2)
X          fprintf(stderr, "\nWhale realloc problems.\n");
X      finish(9);
X    }
X  baby = oldwh;
X  for (mom = 0; mom < oldwh; mom++)
X    {
X      if ((whale[mom].sex == 'F') && (whale[mom].energy >= enermed))
X        {
X          pop = attract(mom);
X          if (whale[pop].sex != 'M')
X              if (debug >= 1)
X                  fprintf(stderr, "\n mate(): No males found!\n");
X              /* Take care of the hard part first, pass on the genes */
X          noclone = (Ushort) randout();
X          mateswit = 0;
X          if (whale[pop].hunttype == whale[mom].hunttype)
X              mateswit |= 0x01;
X          if (whale[pop].hgperchr == whale[mom].hgperchr)
X              mateswit |= 0x02;
X          if (whale[pop].feedtype == whale[mom].feedtype)
X              mateswit |= 0x04;
X          if (whale[pop].fgperchr == whale[mom].fgperchr)
X              mateswit |= 0x08;
X              /* Will increase number of case statements ------
X                  if (whale[pop].countgene == whale[mom].countgene)
X                      mateswit |= 0x10;
X                  if (whale[pop].extragene == whale[mom].extragene)
X                      mateswit |= 0x20;
X              ------*/
X          if (whale[pop].hgperchr == '0' || whale[mom].hgperchr == '0' ||
X                  whale[pop].fgperchr == '0' || whale[mom].fgperchr == '0')
X              mateswit = -1;
X          switch(mateswit)
X            {
X                      /* "Random" whales don't mate: */
X              case -1:
X                  nobaby++;
X                  break;
X                      /* Good - Good: */
X              case 0x0F:
X                  hgjoin1();
X                  fgjoin1();
X                  break;
X                      /* Good - Fair: */
X              case 0x0D:
X                  hgjoin1();
X                  if (INBREED1)
X                      fgjoin1();
X                  else
X                      fgjoin2();
X                  break;
X                      /* Fair - Good: */
X              case 0x07:
X                  if (INBREED1)
X                      hgjoin1();
X                  else
X                      hgjoin2();
X                  fgjoin1();
X                  break;
X                      /* Fair - Fair: */
X              case 0x05:
X                  if (INBREED1)
X                    {
X                      hgjoin1();
X                      fgjoin1();
X                    }
X                  else
X                    {
X                      hgjoin2();
X                      fgjoin2();
X                    }
X                  break;
X                      /* Good - Poor: */
X              case 0x0E:
X              case 0x0C:
X                  if (!INBREED2)
X                    {
X                      nobaby++;
X                      break;
X                    }
X                  hgjoin1();
X                  fgjoin2();
X                  break;
X                      /* Poor - Good: */
X              case 0x0B:
X              case 0x03:
X                  if (!INBREED2)
X                    {
X                      nobaby++;
X                      break;
X                    }
X                  hgjoin2();
X                  fgjoin1();
X                  break;
X                      /* Fair - Poor: */
X              case 0x04:
X              case 0x06:
X                  if (!INBREED2)
X                    {
X                      nobaby++;
X                      break;
X                    }
X                  hgjoin1();
X                  fgjoin2();
X                  break;
X                      /* Poor - Fair: */
X              case 0x01:
X              case 0x09:
X                  if (!INBREED2)
X                    {
X                      nobaby++;
X                      break;
X                    }
X                  hgjoin2();
X                  fgjoin1();
X                  break;
X                      /* Poor - Poor: */
X              case 0x0A:
X              case 0x08:
X              case 0x02:
X              case 0x00:
X                  if (!INBREED2)
X                    {
X                      nobaby++;
X                      break;
X                    }
X                  hgjoin2();
X                  fgjoin2();
X                  break;
X              default:
X                  if (debug >= 2)
X                      fprintf(stderr,
X                              "mate(): gene types switch value wrong\n");
X                  exit(24);
X                  break;
X            }
X          if (nobaby)
X            {
X              nobaby = 0;
X              continue;
X            }
X          else
X            {
X                      /* Finish initializing baby whale */
X              whaleload(baby, 2);    /* Ver 1.10: count-, extra-, gene init */
X              genes[0] = whale[baby].hunttype;
X              genes[1] = whale[baby].hgperchr;
X              genes[2] = whale[baby].feedtype;
X              genes[3] = whale[baby].fgperchr;
X              genes[4] = whale[baby].countgene;
X              genes[5] = whale[baby].extragene;
X              genes[6] = '\0';
X              strncpy(whale[baby].self.gns, genes, 7);
X              whale[baby].father = whale[pop].self;
X              whale[baby].mother = whale[mom].self;
X                 /* Compute ancestral 'distance' from 'original' whales */
X              whale[baby].ancesmax = MAX(whale[mom].ancesmax,
X                                             whale[pop].ancesmax) + 1;
X              whale[baby].ancesmin = MIN(whale[mom].ancesmin,
X                                             whale[pop].ancesmin) + 1;
X              whale[baby].ancesave = AVE(whale[mom].ancesave,
X                                             whale[pop].ancesave) + 1000;
X              tiny = (Ushort) randout();
X              if (tiny % 2)
X                  whale[baby].sex = 'M';
X              else
X                  whale[baby].sex = 'F';
X                      /* And update parents */
X              whale[mom].offspr[whale[mom].childex] = whale[baby].self;
X              whale[mom].allchldn++;
X              whale[mom].childex++;
X              if (whale[mom].childex >= 44 && whale[mom].childex < 50)
X                  if (debug >= 2)
X                      fprintf(stderr,
X                              "mate(): wh[%d].offspr array 90%% FULL\n", mom);
X              if (whale[mom].childex >= 50)
X                {
X                  if (debug >= 2)
X                    {
X                      fprintf(stderr,
X                              "\nmate(): wh[%d].offspr array FULL\n", mom);
X                      fprintf(stderr,
X                              " *** WRAPPING AROUND ***\n");
X                      fprintf(stderr,
X                              "  and WRITING WHALE to offspring file\n\n");
X                    }
X                  kidsout(mom);
X                  whale[mom].offspr[0] = whale[baby].self;
X                  whale[mom].childex = 1;
X                }
X              whale[pop].offspr[whale[pop].childex] = whale[baby].self;
X              whale[pop].allchldn++;
X              whale[pop].childex++;
X              if (whale[pop].childex >= 34 && whale[pop].childex < 50)
X                  if (debug >= 2)
X                      fprintf(stderr,
X                              "mate(): wh[%d].offspr array 70%% FULL\n", pop);
X              if (whale[pop].childex >= 50)
X                {
X                  if (debug >= 2)
X                    {
X                      fprintf(stderr,
X                              "\nmate(): wh[%d].offspr array FULL\n", pop);
X                      fprintf(stderr,
X                              " *** WRAPPING AROUND ***\n");
X                      fprintf(stderr,
X                              "  and WRITING WHALE to offspring file\n\n");
X                    }
X                  kidsout(pop);
X                  whale[pop].offspr[0] = whale[baby].self;
X                  whale[pop].childex = 1;
X                }
X                  /* Next baby */
X              baby++;
X              if (baby > numwh)
X                  if (debug >= 1)
X                      fprintf(stderr, "\n mate(): Genocide Alert!\n");
X            }
X        }
X    }
X  if (baby < numwh)
X    {
X      numwh = baby;
X      whale = (whale_type *) realloc((char *) whale, (numwh * whale_size));
X      if (whale == NULL)
X        {
X          if (debug >= 2)
X              fprintf(stderr, "\nWhale realloc problems.\n");
X          finish(9);
X        }
X    }
X  for (j = 0; j < oldwh; j++)
X    {
X      whale[j].locatn = whaleplace();
X      whale[j].lastfed = 1000000;
X      if (whale[j].energy > 9999)
X        {
X          whale[j].energy = 1000000;
X          whale[j].age++;
X        }
X    }
X  if (debug >= 9)
X      fprintf(stderr, "mate(): truwh = %2d\n", truwh);
X  truwh += baby - oldwh;
X      if (debug >= 9)
X          fprintf(stderr, "mate(): truwh = %2d, baby = %2d\n", truwh, baby);
X  countwhales();
X}
SHAR_EOF
if test 29390 -ne "`wc -c < 'whpl.c3'`"
then
	echo shar: error transmitting "'whpl.c3'" '(should have been 29390 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.
                                |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~