[comp.sources.misc] v07i074: Whales and Plankton, part 01/13

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

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

[[ I just *love* it when sun.com gets its hands on an address and changes
   it to point to lethevax.hell.org.  [ 1/2 ;-) ]

   Once upon a time, there was a simpleminded computer simulation, Conway's
   "Life".  Then there was a slightly more complex one, described in an
   article in the prehistoric ;-) computer magazine KILOBAUD MICROCOMPUTING
   which set dumb browsers up against equally dumb leaves, with the notion of
   food supply added to Conway's simulation.  (For those interested:  I don't
   remember which issue, but it had to be in the 1978-1982 period, and the
   title was "Nature Red in Tooth and Claw."  The program ran in BASIC on an
   OSI C2P (how's *that* for archaic?).)

   This is the logical next step in the progression:  simple genetic rules
   added to the browsers-and-leaves version of "life".  Enjoy.  ++bsa        ]]

# whpl01of13.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 Mar 18 09:47:15 MST 1989
export PATH; PATH=/bin:$PATH
echo shar: extracting "'README'" '(11712 characters)'
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
X
X#============================================================================#
X
X                      Whales & Plankton README file
X
X#============================================================================#
X
X     Copyright (c) 1987, 1988, 1989   Bob Loy
X 
X     Please don't try to make money from whpl.c or associated files whpl.h,
X         whx.c, genes.c, whio.c, or rando.c.  Also, don't be changing my
X         name in this notice.
X     Permission is otherwise granted to the user to freely delete or modify
X         or add to any of the code in the above-named source files.
X 
X     In other words, Experiment!
X
X#============================================================================#
X
X@@  Table of contents of the de-archived files:
X
X         total 355
X        -rw-r--r--    11712    README
X        -rw-r--r--    13358    dealwh.c
X        -rw-r--r--    10720    enerank.c
X        -rw-r--r--    13891    genes.c
X        -rw-r--r--    28649    genes.c2
X        -rw-r--r--     1663    makefile
X        -rw-r--r--    12782    rando.c
X        -rwxr-xr-x      167    rebuild
X        -rw-r--r--    22016    sortcount.c
X        -rw-r--r--    17969    statgene.c
X        -rw-r--r--    25953    symmet.c
X        -rw-r--r--    18374    whio.c
X        -rw-r--r--    29258    whio.c2
X        -rw-r--r--    27590    whio.c3
X        -rw-r--r--     5128    whpl.c
X        -rw-r--r--    28498    whpl.c2
X        -rw-r--r--    29390    whpl.c3
X        -rw-r--r--    11048    whpl.h
X        -rw-r--r--    19370    whx.c
X        -rw-r--r--    29028    whx.c2
X 
X#----------------------------------------------------------------------------#
X
X@@  Rebuilding the source code from the de-archived files:
X
X     Type:  "chmod 755 rebuild"  to make the shell script 'rebuild'
X        executable.
X
X     Run:  "rebuild"  which does the following:
X        cat genes.c2 >> genes.c
X        cat whio.c2 >> whio.c
X        cat whio.c3 >> whio.c
X        cat whpl.c2 >> whpl.c
X        cat whpl.c3 >> whpl.c
X        cat whx.c2 >> whx.c
X        rm -f *.c2 *.c3
X
X#----------------------------------------------------------------------------#
X
X@@  Compiling Whales & Plankton with the makefile:
X
X     To compile everything, get all the .h & .c files into one directory
X        along with the makefile and type:  "make all".  See the makefile
X        for more information.
X
X     Note:
X        the -DSUN opt in the makefile, along with the invocation of the
X        -lpixrect library (usually /usr/lib/libpixrect.a on most Suns),
X        enable compiling of a module which displays on Sun bit-mapped
X        workstations.  Remove these two if attempting to compile for other
X        environments.  The source should probably compile and run under
X        most UNIX machines, though there are no guarantees.  It has been
X        extensively tested on a Sun 3/50 running in a 3/180 (or 3/160)
X        served network under SunOS (UNIX) 3.4.2.
X
X#----------------------------------------------------------------------------#
X
X@@  Running Whales & Plankton:
X
X     Type:  "whx"  and the program will start.  The run, taking roughly two
X        hours on a Sun 3/50 workstation (there are ways to shorten this),
X        and controlled by constants in the header file whpl.h, starts by
X        creating an internal array of size AREA and heigth VBIAS.  This
X        will be randomly filled with plankton for the whales to feed on.
X        Then a count of NUMWH whales will be created with random genesets
X        (even-numbered whales (including #0) will be female; odd, male)
X        and they will start 'swimming' around the array hunting for, and
X        feeding off of the plankton, which will periodically regrow when
X        they are too completely diminished.  If running on a Sun, and
X        compiled with the proper flags & library, this plankton diminish/
X        regrow cycle will be periodically displayed.
X     Based on a do-loop in the main() function, sometimes the weaker whales
X        (the ones not eating very much plankton) will be eliminated.  Other
X        times in that loop, the mate() function will be called to create
X        new offspring containing a mixture of genes from their parents.
X        After a period of time governed by MONTHS, the program will finish,
X        and four files will be written out.  The three important ones:
X           whs120000 - a statistics file rating the whales from best to least
X           whc120000 - a file of all the details of all the whales
X           wha1200   - an archive file with ID's of the whales of this run
X     While all this is going on, there'll also be text output on the screen.
X
X     Obviously, changes in the values of the defined constants in whpl.h,
X        and/or changes to the do-loop in main(), will change the parameters
X        of the run.  But there is also a third way, using command line
X        modifiers (options).  These are covered in detail in the "Examples"
X        section at the top of whio.c.
X
X     One run by itself, of course, won't genetically improve the whale
X        breed very much.  For this purpose, the -i option is used to read
X        a whale detail file back into another run to take up where the
X        previous run left off.  There is also an option, -y (coupled with
X        -p), which allows setting up very long (say overnight) runs, which
X        will write out interim whale files periodically.
X
X     There are two other modes (much quicker) under which whx can run:
X        The -t (sometimes with the -v option as well) command line option
X           can be used to show the 'tracks' of individual whales.
X        The -w option creates a file of "blank" whales for editing by hand.
X        A normal run of hunt/feed/die/mate cycles doesn't happen when these
X           options are in effect.
X
X     Finally, there are five stand-alone utility programs which manipulate
X        and/or report on the whale files output from whx.
X
X     A more detailed explanation of running whx and the utilities will be
X        found at the top of whx.c under the "General Comments" section.
X
X#----------------------------------------------------------------------------#
X
X@@  What whpl.c & associated files do:
X
X     "Whales & Plankton" (whpl) is a program which models a small ecology
X  and is a study of genetic algorithms.
X
X     As an ecological model, it is almost mindlessly simple, with only one
X  preditor and one prey.
X
X     As a platform for study of genetic algorithms, it has certain strengths
X  and certain weaknesses:
X     Mating different parents to improve the algorithm -- The 'chromosomes'
X        involved are not precisely the classic Holland character strings, but
X        they do get a thorough mix, and the whales do indeed improve as the
X        generations proceed.
X           There are a total of: (5 * 5) * (5 * 5) = 625  different 'breeds'
X        -- variations on chromosomes and genes (not to mention 'random'
X        whales available as controls) -- of whales (just one 'breed' of very
X        dumb plankton) which can be tested.  Minimal C-language experience,
X        coupled with a fair amount of study of the format of the file genes.c,
X        will allow the user to create his or her own genesets, increasing the
X        number of breeds to: (5 * 6)*(5 * 6) = 900, or (35)*(35) = 1225, and
X        so on and on indefinitely..
X     Gene Crossover -- The fundamental unit in whpl.c is the 'gene'.  The
X        chromosomes are made up of a certain number of genes, which are
X        freely mixed in the mating algorithm.  The ability to cut the genes
X        themselves, which would be a more complete crossover algorithm, is
X        not available in version 1.10, but could be easily added by a
X        programmer with intermediate C-language experience.  This would
X        be a useful addition, as the "16 genes per chromosome type of whale"
X        presently cannot really produce much in the way variation in its
X        offspring.  Of course, at this point, the preceding sentence is
X        meaningless to the reader, but another way of putting it is that
X        Whales & Plankton version 1.10 really only comes with a total of:
X        (4 * 5) * (4 * 5) = 400  useful breeds.  Read the header comments
X        of the file genes.c, and then re-read this, and things should be
X        clearer.
X     Mutation -- Not implemented in version 1.10, but the necesary "hooks"
X        are already in place for it to be added by (where have we heard this
X        before?) a programmer with intermediate C-language experience.
X
X#----------------------------------------------------------------------------#
X
X@@  Modifying Whales & Plankton source:
X
X     Here is a summary (actually a guess) of what may be accomplished at
X  different levels of C-proficiency:
X     Beginner level -- 
X        Changing header file constants:  Merely changing numbers can have
X           a major effect on how and how long whx will run.
X        Adding gene sets:  
X           Simply crib from another gene set as a starting point.  The
X           easy part is adding another switch statement to the function
X           (genesets() in genes.c).  The hard part is laboriously plotting
X           the X-Y location effect of the new genes you may want to add.
X     "Confident" level -- 
X        Modifying the main program do-loop in main() in whx.c.  Yes, it
X           could be laid out a bit cleaner, but it's still readable and
X           well-commented code.
X     Accomplished level -- 
X        Adding more genetic mixing to the mate() function (see 'Gene
X           Crossover', and 'Mutation' in the "What whpl.c & associated
X           files do:" section above).  Not really that hard, but the
X           mate() function is already one of the longest and most com-
X           plicated functions in whpl.
X     Expert level -- 
X        Including Whales & Plankton in a larger eco-program:  I suspect
X           this would be pretty difficult.  The present code is probably
X           not modular enough to easily shoehorn into a bigger system.
X
X#----------------------------------------------------------------------------#
X
X@@  Finding more information about Whales & Plankton:
X
X     The whpl system of programs is self-documenting; the character '@' is
X  used as a key:
X     A search for the string "@@@" will find the lines with the source
X        file names.
X     A search for the string "@@" will also get function names and a short
X        description of each function.
X     And a search for the single "@" will also find all the other comment
X        lines at the tops of files and at the tops of individual functions.
X
X     So a utility like the Unix "grep", for example, can be used to pull
X  out the "overview" comments from one or more of the whpl-associated files.
X
X     There are also some special-purpose keys which are a subset of the
X  above examples:
X     Search for "@#" to find only the top-of-file comments.
X     Search for "@^" to find comments which apply to input and output.
X
X  See comments at top of whx.c for how to run the program; see comments at
X     top of whio.c for command line examples and comments about file I/O;
X     see comments in genes.c for explanations of breeds and genes; and see
X     individual functions for more specific comments.
X
X#============================================================================#
X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X                                |
X             Bob Loy            |     Life is the detour you take on the
X    ...!sun!sunburn!gtx!loy     |     way to where you're really going.
X                                |
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X
SHAR_EOF
if test 11712 -ne "`wc -c < 'README'`"
then
	echo shar: error transmitting "'README'" '(should have been 11712 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'makefile'" '(1663 characters)'
if test -f 'makefile'
then
	echo shar: will not over-write existing file "'makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'makefile'
X#
X#============================================================================#
X#
X#  makefile     1.2
X#    88/12/16
X#
X#  Whales & Plankton  makefile  1988   Bob Loy
X#
X#     Invoke with:  "make target", e.g.,  make whx , or  make utl 
X#
X#     Change the executable names to anything easier to type, e.g.,
X#        cc $(CFLAGS) sortcount.c -o sortcount  to
X#        cc $(CFLAGS) sortcount.c -o sor
X#
X#     -DSUN opt, along with -lpixrect library, enable compiling of
X#        a module which displays on Sun bit-mapped workstations.  
X#        Remove these two if attempting to compile for other
X#        environments.  whx should probably compile and run under
X#        most UNIX machines, though there are no guarantees.  whx
X#        has been extensively tested on a Sun 3/50 running in a
X#        3/160-served network under SunOS (UNIX) 3.4.2.
X#
X#----------------------------------------------------------------------------#
X#
X
XBIN=.
XOPT=-O
XCFLAGS=$(OPT) -DSUN 
XCC=cc
X
Xall: utl whx
Xutl: sortcount enerank dealwh statgene symmet
X
X
Xsortcount: sortcount.c
X	cc $(CFLAGS) sortcount.c -o sortcount
X
Xenerank: enerank.c
X	cc $(CFLAGS) enerank.c -o enerank
X
Xdealwh: dealwh.c
X	cc $(CFLAGS) dealwh.c -o dealwh
X
Xstatgene: statgene.c
X	cc $(CFLAGS) statgene.c -o statgene
X
Xsymmet: whpl.h symmet.c
X	cc $(CFLAGS) symmet.c -o symmet
X
X
Xrando.o: rando.c
X	cc $(CFLAGS) -c rando.c
X
Xwhio.o: whpl.h whio.c
X	cc $(CFLAGS) -c whio.c
X
Xgenes.o: whpl.h genes.c
X	cc $(CFLAGS) -c genes.c
X
Xwhpl.o: whpl.h whpl.c
X	cc $(CFLAGS) -c whpl.c
X
Xwhx.o: whpl.h whx.c
X	cc $(CFLAGS) -c whx.c
X
Xwhx: whx.o whpl.o genes.o whio.o rando.o
X	cc $(CFLAGS) whx.o whpl.o genes.o whio.o rando.o -lm -lpixrect -o whx
X
SHAR_EOF
if test 1663 -ne "`wc -c < 'makefile'`"
then
	echo shar: error transmitting "'makefile'" '(should have been 1663 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'rando.c'" '(12782 characters)'
if test -f 'rando.c'
then
	echo shar: will not over-write existing file "'rando.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rando.c'
X
X/*****************************************************************************
X *
X *   Copyright (c) 1987, 1988   Bob Loy
X *
X *   Please don't try to make money from whpl.c or associated files whpl.h,
X *       whx.c, genes.c, whio.c, or rando.c.  Also, don't be changing my
X *       name in this notice.
X *   Permission is otherwise granted to the user to freely delete or modify
X *       or add to any of the code in the above-named source files.
X *
X *   In other words, Experiment!
X *
X *****************************************************************************/
X#ifndef lint
X   static char sccsid[] = "  rando.c     1.8  ";
X   static char dateid[] = "    88/10/30  ";
X#endif
X/*@#***********************************************************************
X@@#  
X@@@#  rando.c - State-of-the-Art (?)  Software Random Number Generator.
X@@#  
X@#         contains routines:
X@#  
X@#             long  dateseed();
X@#             void  ranarray();
X@#             short nextrand();
X@#             void  randroll();
X@#             void  randinit();
X@#             long  randout();
X@#             long  randsize();
X@#  
X@#    Borrows heavily from Knuth's Seminumerical Algorithms (The Art of
X@#    Computer Programming,  Vol 2;  2nd Edition).  Program essentially
X@#    has two (almost completly) uncorrelated random number generators
X@#    running in parallel; one is used to 'shuffle' the output of the
X@#    other.  For applications using random numbers which are heavily
X@#    affected by the SEQUENCE of the random values fed to them, this
X@#    program can make a library random number function 'more random'
X@#    by removing dependencies from between successive generator terms.
X@#  
X@#*************************************************************************/
X
X
X/**************************************************************************
X@
X@@ top-level declaration - Two global 64-element arrays of random numbers,
X@  and their sundry pointers and indexes.  Ranarr[] is composed of true
X@  long integers, while sixarr[]'s elements are actually only a six-bit
X@  field.  If the 'static' storage class specifier is removed from the
X@  array declarations, they will be exported to the linker, where the
X@  application program can, if some care is used, use them for extremely
X@  fast random number calls.  For example, if ranarr[] is read sequen-
X@  tially, a different ordering of random values will be obtained than
X@  by calls to randout().  Function randinit() is used to initially fill
X@  the two arrays.  After that, 64 calls to nextrand() will load sixarr[]
X@  with a completely new set of values; the same cannot be said for
X@  randout() and ranarr[], due to the random access nature of the 'shuf-
X@  fling' algorithm this program uses.
X@**************************************************************************/
X
X#include <stdio.h>
X
Xextern long   lrand48();
Xextern void   srand48();
Xstatic long   ranarr[64];
Xstatic short  sixarr[64];
Xstatic short *sixptr = sixarr;
Xstatic short  sixdex = 0;
X
X
X/**************************************************************************
X@
X@@ long dateseed() - Takes a pipe containing the date created from a system
X@  call and uses the minutes and seconds in a function to develop
X@  a long integer to be used as a seed to the "drand48()" family of
X@  random number generators.  For portability considerations, the date
X@  variables are taken from the date command's return line (example:
X@  Fri Jan 30 01:21:14 MST 1987), rather than from any particular sys-
X@  tem's internal date structure or variable.
X@**************************************************************************/
X
Xlong
Xdateseed()
X{
X  FILE  *datepipe;
X  char   datstr[82];
X  long   seed;
X  int    min, sec, sum;
X
X  datepipe = popen("date", "r");
X  fgets(datstr, 80, datepipe);
X  pclose(datepipe);
X  sscanf(datstr, "%*s%*s%*d%*d%*c %d %*c %d", &min, &sec);
X  sum = min + sec + 2;
X  seed = (sum * 1000 + sec) * 10000 + (sec * 1000 + sum);
X  return(seed);
X}
X
X
X/**************************************************************************
X@
X@@ void ranarray() - Loads a 64-element array (the 'shuffled' array) with
X@  successive calls to the seeded library function lrand48().  srand48()
X@  & lrand48() are used rather than the older rand() & srand(), as they
X@  are based on a better linear congruential algorithm and have superior
X@  spectral properties in many implementations.  One extra note:  the
X@  drand48() family does a good job of getting rid of the rightmost (least
X@  likely to be random) bits of its internal function.  If another generator
X@  is substituted for lrand48(), a right shift may be in order in this
X@  function before storing in ranarr[i]; shift value being dependent,
X@  of couse, on whether the application program can handle such scaling
X@  without being negatively affected.
X@**************************************************************************/
X
Xvoid
Xranarray()
X{
X  int    i;
X  long   ds;
X
X  ds = dateseed();
X  srand48(ds);
X  for (i = 0; i < 64; i++)
X      ranarr[i] = lrand48();
X}
X
X
X/**************************************************************************
X@
X@@ short nextrand() - This is the other random number algorithm, which does
X@  the 'shuffling.'  It is Mitchell & Moore's additive generator sequence
X@  Xn = (Xn-24 + Xn-55) mod m ["n-##" being subscripts to X], where m is
X@  even, and n >= 55 (in this case n = 64, from sixarr[64]).  Knuth writes:
X@  "Therefore it may well prove to be the very BEST source of random
X@   numbers for practical purposes.  The only reason it is difficult
X@   to recommend ... wholeheartedly is that there is still very little
X@   theory to prove that it does or does not have desirable randomness
X@   properties; essentially all we know for sure is that the period is
X@   very long, and this is not enough." pp 27-28.  So trust it or not, it
X@  is certainly good enough to pick from the output of lrand48(), for
X@  even if this function got stuck at one value, this program will sim-
X@  ply pass along an unmodified lrand48()'s return.
X@    If this function is to be accessed directly by external calls, the
X@  first call should be preceeded by a call to randinit().
X@**************************************************************************/
X
Xshort
Xnextrand()
X{
X  short  next;
X  short  i, j, k;
X
X  k = sixdex;
X  j = (k + 41) & 0x3F;
X  i = (k + 10) & 0x3F;
X  next = *(sixptr + i) + *(sixptr + j);
X  next = next & 0x3F;
X  *(sixptr + k) = next;
X  sixdex = (sixdex + 1) & 0x3F;
X  return(next);
X}
X
X
X/**************************************************************************
X@
X@@ void randroll() - Two approaches here to 'seed' the nextrand() array
X@  sixarr[64]:  First fills it with a pre-randomized sequence (loaded
X@  from onearr[] & twoarr[]; two arrays used because at least one system
X@  had problems with initializing all 64 characters into one array).
X@  Then dateseed() is called again.  Many times the datepipe created by
X@  the call here will be a duplicate of the one created by the dateseed()
X@  call in ranarray(), but occasionally the seconds boundary will be
X@  crossed.  This adds one last element of decoupling to the two random
X@  functions.  Main purpose of this function is to call nextrand() at
X@  least 250 times to scramble and randomize sixarr[64].
X@  *The line marked with the null comment is an optional statement,
X@   which starts the seeding at a random point in sixarr[64], but
X@   at the cost of creating a coupling to the lrand48() generator.
X@**************************************************************************/
X
Xvoid
Xrandroll()
X{
X  int    i, j;
X  long   seed;
X  int    roll;
X  static char onearr[] = {"BfoClMGaJIhKkbNpEOLCdgIjdEPmNAHF"};
X  static char twoarr[] = {"nDiOGecLJaMfpKgohbncjikAlPBFHDem"};
X
X  for (i = 0; i < 32; i++)
X      sixarr[i] = (short) (onearr[i] & 0x3F);
X  for (i = 32, j = 0; i < 64; i++, j++)
X      sixarr[i] = (short) (twoarr[j] & 0x3F);
X  sixdex = (short) (lrand48() & 0x3f);                   /*   */
X  seed = dateseed();
X  roll = (int) (seed / 3000000);
X  roll += 250;
X  for (i = 0; i < roll; i++)
X      nextrand();
X}
X
X
X/**************************************************************************
X@
X@@ void randinit() - Initialization function for ranarr[64] and sixarr[64].
X@**************************************************************************/
X
Xvoid
Xrandinit()
X{
X  ranarray();        /*  initializes ranarr[64]  */
X  randroll();        /*  initializes sixarr[64]  */
X}
X
X
X/**************************************************************************
X@
X@@ long randout() - Uses nextrand to access a value in ranarr[64] for the
X@  return value, then replaces it with the latest call to lrand48().  The
X@  first call to this function should be preceeded by a call to randinit().
X@**************************************************************************/
X
Xlong
Xrandout()
X{
X  short  index;
X  long   in, out;
X
X  index = nextrand();
X  in = lrand48();
X  out = ranarr[index];
X  ranarr[index] = in;
X  return(out);
X}
X
X
X/**************************************************************************
X@
X@@ long randsize(limit) - A utility function for returning a random value
X@  less than the next power of two greater than the value of the passed
X@  parameter.  Useful starting point for creating random values in bases
X@  other than two.
X@**************************************************************************/
X
Xlong
Xrandsize(lim)
X  long   lim;
X{
X  long   slice;
X
X  if  (lim <= 2)                slice = randout() & 0x1;
X  if ((lim > 2) && (lim <= 4))  slice = randout() & 0x3;
X  if ((lim > 4) && (lim <= 8))  slice = randout() & 0x7;
X  if ((lim > 8) && (lim <= 16)) slice = randout() & 0xF;
X  if ((lim > 16) && (lim <= 32))   slice = randout() & 0x1F;
X  if ((lim > 32) && (lim <= 64))   slice = randout() & 0x3F;
X  if ((lim > 64) && (lim <= 128))  slice = randout() & 0x7F;
X  if ((lim > 128) && (lim <= 256)) slice = randout() & 0xFF;
X  if ((lim > 256) && (lim <= 512))   slice = randout() & 0x1FF;
X  if ((lim > 512) && (lim <= 1024))  slice = randout() & 0x3FF;
X  if ((lim > 1024) && (lim <= 2048)) slice = randout() & 0x7FF;
X  if ((lim > 2048) && (lim <= 4096)) slice = randout() & 0xFFF;
X  if ((lim > 4096) && (lim <= 8192))   slice = randout() & 0x1FFF;
X  if ((lim > 8192) && (lim <= 16384))  slice = randout() & 0x3FFF;
X  if ((lim > 16384) && (lim <= 32768)) slice = randout() & 0x7FFF;
X  if ((lim > 32768) && (lim <= 65536)) slice = randout() & 0xFFFF;
X  if ((lim > 65536) && (lim <= 131072))   slice = randout() & 0x1FFFF;
X  if ((lim > 131072) && (lim <= 262144))  slice = randout() & 0x3FFFF;
X  if ((lim > 262144) && (lim <= 524288))  slice = randout() & 0x7FFFF;
X  if ((lim > 524288) && (lim <= 1048576)) slice = randout() & 0xFFFFF;
X  if ((lim > 1048576) && (lim <= 2097152))  slice = randout() & 0x1FFFFF;
X  if ((lim > 2097152) && (lim <= 4194304))  slice = randout() & 0x3FFFFF;
X  if ((lim > 4194304) && (lim <= 8388608))  slice = randout() & 0x7FFFFF;
X  if ((lim > 8388608) && (lim <= 16777216)) slice = randout() & 0xFFFFFF;
X  if ((lim > 16777216) && (lim <= 33554432))   slice = randout() & 0x1FFFFFF;
X  if ((lim > 33554432) && (lim <= 67108864))   slice = randout() & 0x3FFFFFF;
X  if ((lim > 67108864) && (lim <= 134217728))  slice = randout() & 0x7FFFFFF;
X  if ((lim > 134217728) && (lim <= 268435456)) slice = randout() & 0xFFFFFFF;
X  if((lim > 268435456) && (lim <= 536870912))   slice = randout() & 0x1FFFFFFF;
X  if((lim > 536870912) && (lim <= 1073741824))  slice = randout() & 0x3FFFFFFF;
X  if((lim > 1073741824) && (lim <= 2147483648)) slice = randout() & 0x7FFFFFFF;
X      /* lrand48 returns SIGNED long type...
X  if((lim > 2147483648) && (lim <= 4294967296)) slice = randout() & 0xFFFFFFFF;
X      ...so this line is commented out for Sun, Unix 3.4.2. */
X  return (slice);
X}
X
X/**************************************************************************
X@
X@@ void main() - Example (commented out)
X@           ******************************
X
Xvoid
Xmain()
X{
X  long    value;
X  short   j;
X  short   small;
X  unsigned  short   usmall;
X 
X 
X  randinit();
X 
X  printf("\n");
X  for(j = 0; j < 6; j++) {
X      value = randout();
X      printf("%14d\n", value);
X    }
X  printf("\n");
X 
X  for(j = 0; j < 6; j++) {
X      value = nextrand();
X      printf("            %2d\n", value);
X    }
X  printf("\n");
X 
X  for(j = 0; j < 3; j++) {
X      do{
X          value = randsize(999);
X        } while(value > 999);
X      printf("           %3d\n", value);
X    }
X  printf("\n");
X
X  for(j = 0; j < 8; j++) {
X      value = randout();
X          /* Be sure to make unsigned if smaller: * /  <--Nested Comment...
X      small = (short) value;
X      usmall = (unsigned  short) value;
X      printf("%14d   %6d  %6d\n", value, small, usmall);
X    }
X  printf("\n");
X}
X
X@**************************************************************************/
X
SHAR_EOF
if test 12782 -ne "`wc -c < 'rando.c'`"
then
	echo shar: error transmitting "'rando.c'" '(should have been 12782 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'rebuild'" '(167 characters)'
if test -f 'rebuild'
then
	echo shar: will not over-write existing file "'rebuild'"
else
sed 's/^X//' << \SHAR_EOF > 'rebuild'
X#!/bin/sh
Xset -v
Xcat genes.c2 >> genes.c
Xcat whio.c2 >> whio.c
Xcat whio.c3 >> whio.c
Xcat whpl.c2 >> whpl.c
Xcat whpl.c3 >> whpl.c
Xcat whx.c2 >> whx.c
X
Xrm -f *.c2 *.c3
X
SHAR_EOF
if test 167 -ne "`wc -c < 'rebuild'`"
then
	echo shar: error transmitting "'rebuild'" '(should have been 167 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.
                                |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~