Generated from util.c with ROBODoc v3.2.2 on Sun Aug 27 19:47:35 2000

TABLE OF CONTENTS

  1. GalaxyNG/Util
  2. Util/Fopen
  3. Util/GOS_copy
  4. Util/GOS_copy
  5. Util/GOS_delete
  6. Util/GOS_fopen
  7. Util/GOS_mkdir
  8. Util/addplanet
  9. Util/alloc
  10. Util/atwar
  11. Util/canseegroup
  12. Util/canseeplanet
  13. Util/cargospace
  14. Util/closeLog
  15. Util/createString
  16. Util/dist
  17. Util/dumpGame
  18. Util/dumpPlanets
  19. Util/dumpPlayers
  20. Util/effectiveIndustry
  21. Util/findPlanet
  22. Util/findgroup
  23. Util/fleetSpeed
  24. Util/frand
  25. Util/frand2
  26. Util/frand3
  27. Util/freebattles
  28. Util/freegame
  29. Util/freestrlist
  30. Util/getstr
  31. Util/groupAttack
  32. Util/groupDefense
  33. Util/groupLocation
  34. Util/groupSpeed
  35. Util/groupx
  36. Util/groupy
  37. Util/isunidentified
  38. Util/isuninhabited
  39. Util/krandom
  40. Util/loadRanTab
  41. Util/makestrlist
  42. Util/nationStatus
  43. Util/noCaseStrcmp
  44. Util/noCaseStrncmp
  45. Util/numOfGroupsInFleet
  46. Util/numberGroup
  47. Util/openLog
  48. Util/pdebug
  49. Util/plog
  50. Util/plogtime
  51. Util/putmap
  52. Util/recall
  53. Util/resetErnie
  54. Util/round2
  55. Util/saveRanTab
  56. Util/savefprintf
  57. Util/send
  58. Util/setproduction
  59. Util/shipmass
  60. Util/ssystem
  61. Util/typeDefense
  62. Util/typeSpeed
  63. Util/typemass
  64. Util/weaponmass

GalaxyNG/Util

NAME
   Util 
FUNCTION
   A collection of frequently used functions.

Util/Fopen

NAME
   Fopen -- try to open a file.
SYNOPSIS
   FILE *Fopen(char *filename, char *mode)
INPUTS
   filename   -- name of the file to open
   mode       -- open mode 
RESULT
   file handle of the opened file.
   Program is aborted if the file could not be opened.
BUGS
   This function should not be used!

Util/GOS_copy

NAME


Util/GOS_copy

NAME


Util/GOS_delete

NAME


Util/GOS_fopen

NAME
   GOS_fopen --
FUNCTION
   Hide OS dependencies.

Util/GOS_mkdir

NAME
   GOS_mkdir -- create a directory
FUNCTION
   Hide OS dependencies.

Util/addplanet

NAME
   addplanet -- add a planet to planet list
SYNOPSIS
   planet *addplanet(void)
FUNCTION
   Creates a planet stucture and adds it to the list of planets. The
   name of the planet is its index number in the list.
SEE ALSO
   planets, planet, create.c, create() 
SOURCE
    planet         *
    addplanet(game *aGame)
    {
      planet         *p;
      int             i;
      char            name[20];
    
      for (p = aGame->planets, i = 1; p; p = p->next, i++);
      p = allocStruct(planet);
    
      addList(&(aGame->planets), p);
      sprintf(name, "%d", i);
      setName(p, name);
      return p;
    }    

Util/alloc

NAME
   alloc -- allocate memory
SYNOPSIS
   void *alloc(unsigned int requestedSize)
FUNCTION
   Try to allocate memory. If the allocation fails, abort
   the program.
RESULT
   Pointer to the allocated memory.
SOURCE
    void           *
    alloc(unsigned int n)
    {
      void           *p;
    
      p = malloc(n);
      if (p == 0) {
        printf("Out of memory\n");
        exit(1);
      }
      return p;
    }    

Util/atwar

NAME
   atwar -- are two players at war?
SYNOPSIS
   int atwar(player *P, player *P2)
RESULT
   TRUE  - players are at war with eachother
   FALSE - they are at peace. 
SOURCE
    int
    atwar(player *P, player *P2)
    {
      alliance       *a;
    
      if (P == P2)
        return 0;
      for (a = P->allies; a; a = a->next)
        if (a->who == P2)
          return 0;
      return 1;
    }    

Util/canseegroup

NAME
   canseegroup -- can a Nation see a group?
SYNOPSIS
   int canseegroup(player *P, group *g)
RESULT
   TRUE if nation P can see group g.
SOURCE
    int
    canseegroup(player *P, group *g)
    {
      group          *g2;
    
      if (g->dist)
        return 0;
      if (g->where->owner == P)
        return 1;
      for (g2 = P->groups; g2; g2 = g2->next)
        if (!g2->dist && g2->where == g->where)
          return 1;
      return 0;
    }    

Util/canseeplanet

NAME
   canseeplanet -- can a Nation see a planet?
SYNOPSIS
   int canseeplanet(player *P, planet *p)
RESULT
   TRUE if nation P can see planet p.
SOURCE
    int
    canseeplanet(player *P, planet *p)
    {
      group          *g;
    
      if (p->owner == P)
        return 1;
      for (g = P->groups; g; g = g->next)
        if (g->dist == 0 && g->where == p)
          return 1;
      return 0;
    }    

Util/cargospace

NAME
   cargospace -- compute cargo space of a ship in a group.
RESULT
   cargo space of one ship in a group at current
   tech levels.
SOURCE
    double
    cargospace(group *g)
    {
      double          size;
    
      size = g->type->cargo;
      return g->cargo * size * (1 + size / 10.0);
    }    

Util/closeLog

NAME
   closeLog -- close log file, (if open)
FUNCTION
   Close the log file opened with openLog(). The function checks
   if the log file is open, so you can call it on a already closed
   log file.
SOURCE
    void
    closeLog()
    {
      if (logFile) {
        fclose(logFile);
        logFile = NULL;
      }
    }    

Util/createString

NAME
   createString -- create a string
SYNOPSIS
   char *createString(char *,...)
   stringcopy = createString(format,...)
FUNCTION
   Creates a string using a printf() like syntax.
RESULT
   stringcopy, pointer to created string.  
SOURCE
    char           *
    createString(char *format,...)
    {
      int             n;
      va_list         ap;
    
      va_start(ap, format);
    #ifdef WIN32
      vsprintf(lineBuffer, format, ap);
    #else
      n = vsnprintf(lineBuffer, LINE_BUFFER_SIZE, format, ap);
      assert(n != -1);
    #endif
      va_end(ap);
      return strdup(lineBuffer);
    }    

Util/dist

NAME
   dist -- distance between two planets
SYNOPSIS
   double dist(planet *p1, planet *p2)
SOURCE
    double
    dist(planet *p1, planet *p2)
    {
      double          dx, dy;
      double          res;
    
      dx = p1->x - p2->x;
      dy = p1->y - p2->y;
      res = sqrt(dx * dx + dy * dy);
      return res;
    }    

Util/dumpGame

NAME
   dumpGame -- dump game data structure to stdout.
NOTES
   For debug purpose. Does not do any thing at the moment.

Util/dumpPlanets

NAME
   dumpPlanets -- dump all planet data to stdout.

Util/dumpPlayers

NAME
   dumpPlayers -- dump all data of the players to stdout

Util/effectiveIndustry

NAME
   effectiveIndustry -- compute effective industry
SYNOPSIS
   double effectiveIndustry(double pop, double ind)
FUNCTION
   Compute the effective industry.
BUGS
   This should have the signature (Planet *p).  
SOURCE
    double
    effectiveIndustry(double pop, double ind)
    {
      double          res;
    
      res = (pop - ind) / 4.0 + ind;
      return res;
    }    

Util/findPlanet

NAME
   findPlanet -- find a planet
SYNOPSIS
   planet     *findPlanet(game *, char *)
   thePlanet = findPlanet(aGame, name)
FUNCTION
   Find a planet in the list of planets using its name.
   The name can be specified in two ways:
   #<planet number at turn 0>
   <current planet name as listed in the turn report>
INPUTS
   aGame  -- game structure.
   name   -- planet's name
SOURCE
    planet         *
    findPlanet(game *aGame, char *name)
    {
      if (name[0] eq '#') {
        char           *c;
    
        for (c = name + 1; *c && isdigit(*c); c++);
        if (!(*c)) {
          return (planet *) numtop(aGame->planets, atoi(name + 1));
        }
        else {
          return NULL;
        }
      }
      else {
        return findElement(planet, aGame->planets, name);
      }
    }    

Util/findgroup

NAME
   findgroup -- find a group
SYNOPSIS
   group     *findgroup(player *, char *)
   theGroup = findgroup(aPlayer, name)
FUNCTION
   Find a group in the list of groups using its name.
   The name is either the ASCII representation of the group
   number of the keyword "MAX" in which case the last group
   in the list is returned.
INPUTS
   aPlayer -- player who's groups will be examined.
   name    -- group name.
SOURCE
    group          *
    findgroup(player *P, char *s)
    {
      group          *g;
    
      g = NULL;
      if (P->groups) {
        if (!noCaseStrcmp(s, "max")) {
          for (g = P->groups; g->next; g = g->next);
        }
        else {
          int             groupNumber;
    
          groupNumber = atoi(s);
          for (g = P->groups; g && (g->number != groupNumber); g = g->next);
        }
      }
      return g;
    }    

Util/fleetSpeed

NAME
   fleetSpeed
SYNOPSIS
   double fleetSpeed(fleetname *fl, group *g)
FUNCTION
   Compute the speed of a fleet, this is the speed of the slowest
   ship in the fleet.  
INPUTS
   fl  -- name of the fleet.
   g   -- list with all groups of the nation that owns the fleet.
RESULT
   Speed of the fleet.
NOTES
   This is a time expensive function since all groups of a nation
   are scanned.
SOURCE
    double
    fleetSpeed(fleetname *fl, group *g)
    {                               /* CB-19980922 */
      double          res = 0, tmp;
      group          *g2;
    
    /* FS Mon Oct 12 14:39:11 MEST 1998  Sometimes people have fleets with * * 
     * 
     * *  * *  * * ships of speed 0.0 */
      for (g2 = g; g2; g2 = g2->next) {
        if (g2->thefleet == fl) {
          res = groupSpeed(g2);
          break;
        }
      }
      for (; g2; g2 = g2->next) {
        if (g2->thefleet == fl) {
          tmp = groupSpeed(g2);
          if (tmp <= res)
            res = tmp;
        }
      }
      return res;
    }    

Util/frand

NAME
   frand -- generate a random float, range [0,x]
SYNOPSIS
   double frand(double x)
FUNCTION
   Generate a random float in the range [0,x] 
BUGS
   Has a non descriptive name.
SEE ALSO
   frand2(), frand3(), krandom()
SOURCE
    double
    frand(double x)
    {
      double          fr;
    
      fr = (double) krandom() / (double) (UINT_MAX);        /* From limits.h */
      return x * fr;
    }    

Util/frand2

NAME
   frand2 -- generate a random float, range [-1,1]
SYNOPSIS
   double frand2(void)
FUNCTION
   Generate a random float in the range [-1,1] 
BUGS
   Has a non descriptive name.
SEE ALSO
   frand(), frand3(), krandom()
SOURCE
    double
    frand2(void)
    {
      return ((double) krandom() / (double) (UINT_MAX)) * 2.0 - 1.0;
    }    

Util/frand3

NAME
   frand3 -- generate a random integer
SYNOPSIS
   int frand3(int r)
FUNCTION
   Generate a random integer in the range [0,r-1] 
BUGS
   This function has a stupid name.
SEE ALSO
   frand2(), krandom()
SOURCE
    int
    frand3(int r)
    {
      return (int) floor(((double) krandom() / (double) (UINT_MAX)) * r);
    }    

Util/freebattles

NAME
   freebattles -- free all memory used by a list of battles.
NOTES
   Useless at the moment.

Util/freegame

NAME
   freegame --
SYNOPSIS
   void freegame(void)
FUNCTION
   Free all memory used by the current game.
BUGS
   Does not work at all.

Util/freestrlist

NAME
   freestrlist -- free memory used by a string list.
SYNOPSIS
   void freestrlist(strlist *s)
FUNCTION
   Free all memory used by a string list. Before
   trying to free the memory used by an element check
   if the element is valid.
SOURCE
    void
    freestrlist(strlist *s)
    {
      strlist        *s2;
    
      pdebug(DFULL, "free strlist\n");
      while (s) {
        validateStruct(strlist, s);
    
        s2 = s->next;
        free(s->str);
        free(s);
        s = s2;
      }
    }    

Util/getstr

NAME
   getstr -- extract a word from a longer string 
SYNOPSIS
   char *getstr(char *s)
   word = getstr(someString)
FUNCTION
   Extract a word from a string of words.  A word is any things that
   is seperated by white spaces or a comma, any string that is
   delimited by quotes ("), or or any string delimited by { }.

   The function is intended to parse a string word by word. It
   should be first called as:

     firstword = getstr(myStringOfWords);

   This gets the first word from the string pointed to by
   myStringOfWords.  Then consecutive calls of

     nextword = getstr(NULL);

   you get the remaining words.

   White spaces inside a quote delimited word are turned into 
   underscores.  

   In a string a ';' signifies the start of a comment. Any words
   after a ';' are not parsed.
 
   In the non comment part ';' and '<' are removed before the words
   are returned.
  
RESULT
   word = a pointer to a nul terminated string.

   Program is aborted if the length of the word is longer than 256,
   since then some is most likely trying to crack your system.
 
   When there are no more words"\0" is returned.
NOTES
   This function can only work on one string at the time since it
   works with a statically allocated buffer.  This function is used
   almost every where in the program.
SOURCE
    char           *
    getstr(char *s)
    {
      static char    *s1;
      static char     buf[256];
      int             i, j;
    
      if (s)
        s1 = s;
      /* first invocation of this function, for an order line.  Each next * *
       * * times, for the same order line, s1 will "progress"  by a word to *
       * * the * right */
      assert(s1 != NULL);
    
      i = 0;
      for (; *s1 && isspace(*s1); s1++);    /* skips spaces */
    
      if (*s1 eq '"') {
    /* Players can enclose name (ie : including spaces) with double quotes */
        for (s1++; *s1 && *s1 != '"';) {
          buf[i] = isspace(*s1) ? '_' : *s1;
          s1++;
          i++;
          assert(i < 256);          /* abort execution if s1 too long */
        }
      }
      else if (*s1 eq '{') {
        for (s1++; *s1 && *s1 != '}';) {
          buf[i] = *s1;
          s1++;
          i++;
          assert(i < 256);          /* abort execution if s1 too long */
        }
      }
      else {
        if (*s1 != ';') {           /* otherwise, it's a comment */
          for (; *s1 && !isspace(*s1) && *s1 != ',';) {
            /* space or ',' can be  used as separators, */
            buf[i] = *s1;
            s1++;
            i++;
            assert(i < 256);        /* abort execution if s1 too long */
          }
        }
      }
    
      buf[i] = '\0';
      if (*s1)
        s1++;                       /* Skip ',' or space */
      /* CB, 19980922. Remove ";" and "<" from names (planets,  ships...), * 
       * * to  * protect machine report from corruption. Don't break messages
       * * * and * comments. */
      i = 0;
      j = 0;
      while (buf[j] && j < 256) {
        if (buf[j] != ';' && buf[j] != '<') {
          buf[i] = buf[j];
          i++;
        }
        j++;
      }
      if (i)
        buf[i] = '\0';
    
      return buf;
    }    

Util/groupAttack

NAME
   groupAttack
SYNOPSIS
   double groupAttack(group *g)
FUNCTION
   Compute the effective attack of a ship in a group. 
   This is the product of its weapon and weapon tech level.
SOURCE
    double
    groupAttack(group *g)
    {
      double          res;
    
      res = g->weapons * g->type->weapons;
      return res;
    }    

Util/groupDefense

NAME
   groupDefense -- shield strength of a ship in group g
SYNOPSIS
   double groupDefense(group *g)
FUNCTION
   Computes the shield strength of a ship in a group.
   Based on the mass of the ship (including cargo) and
   its current tech levels.
SEE ALSO
   typeDefense()
SOURCE
    double
    groupDefense(group *g)
    {
      double          res;
    
      res = g->type->shields * g->shields *
          BATTLEMAGIC / pow(shipmass(g), .333333333333333);
      return res;
    }    

Util/groupLocation

NAME
   groupLocation -- compute location of a group
SYNOPSIS
   planet  *groupLocation(group *g)
FUNCTION
   Determine which planet a group is orbiting.
RESULT
   NULL if the group is in hyperspace, pointer to the 
   planet the group is orbitting otherwise.
SOURCE
    planet         *
    groupLocation(group *g)
    {
      planet         *p;
    
      p = NULL;
      if (g->dist eq 0)
        p = g->where;
      else if (g->dist eq dist(g->where, g->from))
        p = g->from;
      return p;
    }    

Util/groupSpeed

NAME
   groupsSpeed -- compute the speed of a ship in a group of ships.
SYNOPSIS
   double groupSpeed(group *g)
FUNCTION
   Compute the speed of a ship in a group of ships, based on the
   mass of the ship and the drive technology.  
SOURCE
    double
    groupSpeed(group *g)
    {
      double          res;
    
      res = g->type->drive * g->drive * DRIVEMAGIC / shipmass(g);
      return res;
    }    

Util/groupx

NAME
   groupx -- compute x coordinate of a group
SYNOPSIS
   double groupx(group *g)
FUNCTION
   Compute the x coordinate of a group. If a group is at a planet
   this coordinate is the x coordinate of that planet. If the group
   is traveling it is the x coordinate of the vector pointing to the
   destination planet and orginating from the planet of origin, and
   with a length equal to the destination traveled sofar.
SOURCE
    double
    groupx(group *g)
    {
      double          dx, ratio, dis;
      double          res;
    
      dis = dist(g->from, g->where);
      if (!dis)
        return g->where->x;
      dx = g->where->x - g->from->x;
      ratio = g->dist / dis;
      res = g->where->x - ratio * dx;
      return res;
    }    

Util/groupy

NAME
   groupy -- compute y coordinate of a group
SYNOPSIS
   double groupy(group *g)
FUNCTION
   Compute the y coordinate of a group. If a group is at a planet
   this coordinate is the y coordinate of that planet. If the group
   is traveling it is the y coordinate of the vector pointing to the
   destination planet and orginating from the planet of origin, and
   with a length equal to the destination traveled sofar.
SOURCE
    double
    groupy(group *g)
    {
      double          dy, ratio, dis;
      double          res;
    
      dis = dist(g->from, g->where);
      if (!dis)
        return g->where->y;
      dy = g->where->y - g->from->y;
      ratio = g->dist / dis;
      res = g->where->y - ratio * dy;
      return res;
    }    

Util/isunidentified

NAME
   isunidentified -- is a planet unidentified?
SYNOPSIS
   int isunidentified(player *P, planet *p)
FUNCTION
   Is a planet considered unidentified for Nation P?
   This is the case when a planet has an owner, and this
   owner is not P, and P can not see the planet (has no
   groups in orbit at the planet).
INPUTS
   P -- Nation to check for
   p -- planet to check.
RESULT
   TRUE -- planet is unidentified
SOURCE
    int
    isunidentified(player *P, planet *p)
    {
      return (p->owner != NULL && p->owner != P && !canseeplanet(P, p));
    }    

Util/isuninhabited

NAME
   isuninhabited -- is a planet uninhabited?
SYNOPSIS
   int isuninhabited(player *P, planet *p)
INPUTS
   p -- planet to check.
RESULT
   TRUE -- planet is uninhabited
BUGS
   P is not used!
SOURCE
    int
    isuninhabited(player *P, planet *p)
    {
      return (p->owner == NULL);
    }    

Util/krandom

NAME
   krandom -- portable random number generator
SYNOPSIS
   unsigned int krandom(void) 
FUNCTION
   Random number generator based on an algorithm described
   in Donald Knuth's "The art of computer programming".
SEE ALSO
   frand(), frand2(), frand3()
SOURCE
    #define RTAB_LENGTH 55          /* Don't ever change this!!! */
    unsigned int    Ran_tab[RTAB_LENGTH];
    int             Ran_k;
    int             Ran_j;
    
    unsigned int
    krandom(void)
    {
      Ran_tab[Ran_k] += Ran_tab[Ran_j];
      Ran_k--;
      Ran_j--;
      if (Ran_k < 0)
        Ran_k = 54;
      if (Ran_j < 0)
        Ran_j = 54;
      return (Ran_tab[Ran_k]);
    }    

Util/loadRanTab

NAME
   loadRanTab -- load seed values from turn file
FUNCTION
   Load the table with seed values for the random number generator
   from the turn file.
SEE ALSO
   saveRanTab()
SOURCE
    void
    loadRanTab(FILE * f)
    {
      int             i, loaded;
    
      loaded = TRUE;
      for (i = 0; i < RTAB_LENGTH; i++) {
        unsigned int    s;
    
        if (fscanf(f, "%u", &s) != 1) {
          loaded = FALSE;
          break;
        }
        else {
          Ran_tab[i] = s;
        }
      }
      if (loaded) {
        Ran_k = 23;
        Ran_j = 54;
      }
      else {
        plog(LPART, "Failed to load the random table, creating one.\n");
        resetErnie(197162622);
      }
    }    

Util/makestrlist

NAME
   makestrlist -- create an element for a string list
FUNCTION
   
RESULT
   Pointer to an initialized strlist structure.
BUGS
   This function has a wrong name.
SOURCE
    strlist        *
    makestrlist(char *ns)
    {
      strlist        *s;
    
      s = allocStruct(strlist);
    
      s->str = strdup(ns);
      return s;
    }    

Util/nationStatus

NAME
   nationStatus -- compute status of all nations
FUNCTION
   Compute population, industry, and number of planets of all nations.
SOURCE
    void
    nationStatus(game *aGame)
    {
      planet         *aPlanet;
      player         *aPlayer;
    
      for (aPlayer = aGame->players;
           aPlayer;
           aPlayer = aPlayer->next) {
        aPlayer->totPop = 0;
        aPlayer->totInd = 0;
        aPlayer->numberOfPlanets = 0;
        for (aPlanet = aGame->planets;
             aPlanet;
             aPlanet = aPlanet->next) {
          if (aPlanet->owner eq aPlayer) {
            aPlayer->totPop += aPlanet->pop;
            aPlayer->totInd += aPlanet->ind;
            aPlayer->numberOfPlanets++;
          }
        }
      }
    }    

Util/noCaseStrcmp

NAME
   noCaseStrcmp --
SYNOPSIS
   int noCaseStrcmp(char *s, char *t)
FUNCTION
   Compare two strings without paying no attention to the case of
   the letters.
RESULT
    0  s == t
   -1  s < t
    1  s > t
SOURCE
    int
    noCaseStrcmp(char *s, char *t)
    {
      for (; tolower(*s) == tolower(*t); s++, t++)
        if (*s == '\0')
          return 0;
      return (int) (tolower(*s) - tolower(*t));
    }    

Util/noCaseStrncmp

NAME
   noCaseStrncmp --
SYNOPSIS
   int noCaseStrncmp(char *, char *, int)
   result = noCaseStrncmp(s, t, n)
FUNCTION
   Compare two strings without paying no attention to the case of
   the letters, but compare no more than n characters.
RESULT
    0  s == t
   -1  s < t
    1  s > t
SOURCE
    int
    noCaseStrncmp(char *s, char *t, int n)
    {
      for (n--; (tolower(*s) == tolower(*t)) && (n > 0); s++, t++, n--)
        if (*s == '\0')
          return 0;
      return (int) (tolower(*s) - tolower(*t));
    }    

Util/numOfGroupsInFleet

NAME
   numOfGroupsInFleet -- number of groups in a fleet.
SYNOPSIS
   int numOfGroupsInFleet(fleetname *fl, group *g)
FUNCTION
   Count the number of groups in a fleet.
INPUTS
   fl  -- name of the fleet
   g   -- list with all groups of the nation that owns the fleet
RESULT
   Number of groups in the fleet.
NOTES
   This is a time expensive function since all groups of a nation
   are scanned.
SOURCE
    int
    numOfGroupsInFleet(fleetname *fl, group *g)
    {
      group          *g2;
      int             count;
    
      count = 0;
      for (g2 = g; g2; g2 = g2->next) {
        if (g2->thefleet == fl) {
          count++;
        }
      }
    
      return count;
    }    

Util/numberGroup

NAME
   numberGroup -- gives a group a number
SYNOPSIS
   void numberGroup(player *aPlayer, group *aGroup)
FUNCTION
   Number the group with the next available number.
SOURCE
    void
    numberGroup(player *aPlayer, group *aGroup)
    {
      group          *curGroup;
      int             groupNumber;
    
      groupNumber = 0;
      for (curGroup = aPlayer->groups;
           curGroup;
           curGroup = curGroup->next) {
        if (curGroup->number > groupNumber)
          groupNumber = curGroup->number;
      }
      groupNumber++;
      aGroup->number = groupNumber;
    }    

Util/openLog

NAME
   openLog -- open a log file.
FUNCTION
   Open a log file. Close the previous log file if open.
SOURCE
    int
    openLog(char *name, char *mode)
    {
      if (logFile)
        fclose(logFile);
      if ((logFile = GOS_fopen(name, mode)) == NULL) {
        fprintf(stderr, "Could not open log file %s\n", name);
      }
      return 0;
    }    

Util/pdebug

NAME
   pdebug -- dump a message to stdout
SYNOPSIS
   void pdebug(int level, char *format,...)
FUNCTION
   Dump a debug message to stdout. Each message has a debug level.
   Messages are only printed if they have a level below the debug
   level (specified in the global debugLevel).
INPUTS
   level  -- debug level of the message
   format -- format string for the messgage
   ...    -- other parameters
SOURCE
    void
    pdebug(int level, char *format,...)
    {
      va_list         ap;
    
      if (level <= debugLevel) {
        va_start(ap, format);
        vprintf(format, ap);
        va_end(ap);
      }
    }    

Util/plog

NAME
   plog -- dump a messgage to the log file.
SYNOPSIS
   void plog(int level, char *format,...)
FUNCTION
   Dump a log message to the logfile. Each message has a log level.
   Messages are only stored if they have a level below the 
   log level (specified in the global logLevel).
INPUTS
   level  -- log level of the message
   format -- format string for the messgage
   ...    -- other parameters
SOURCE
    void
    plog(int level, char *format,...)
    {
      va_list         ap;
    
      if (level <= logLevel && logFile) {
        va_start(ap, format);
        vfprintf(logFile, format, ap);
        va_end(ap);
      }
    }    

Util/plogtime

NAME
   plogtime -- write current time and date to the log file.
SYNOPSIS
   void plogtime(int level)
SOURCE
    void
    plogtime(int level)
    {
      if (level <= logLevel && logFile) {
        time_t          ttp;
        char            timeBuffer[255];
    
        time(&ttp);
        strftime(timeBuffer, 255, "%H:%M:%S %a %b %d %Y\n", localtime(&ttp));
        fprintf(logFile, "%s", timeBuffer);
      }
    }    

Util/putmap

NAME
   putmap --
FUNCTION
   Put an element on the map.
SOURCE
    void
    putmap(mapdimensions *md, double x, double y, int c)
    {
      int             ix, iy;
    
      ix = (x - md->x1) / (md->x2 - md->x1) * MAPWIDTH;
      iy = (y - md->y1) / (md->y2 - md->y1) * MAPHEIGHT;
      if (ix < 0 || ix >= MAPWIDTH || iy < 0 || iy >= MAPHEIGHT)
        return;
      map[ix][iy] = c;
    }    

Util/recall

NAME
   recall -- recall a group 
SYNOPSIS
   void recall(group *g, planet *p)
FUNCTION
   Make a group that is already underway to a planet return
   to the planet of origin.
INPUTS
   g -- group to be recalled
SOURCE
    void
    recall(group *g)
    {                               /* CB-19980923 */
      planet         *p2;
    
      g->dist = dist(g->from, g->where) - g->dist;
      p2 = g->from;
      g->from = g->where;
      g->where = p2;
    }    

Util/resetErnie

NAME
   resetErnie -- reset random number generator
FUNCTION
   Reset the random number generator.
   Based on a seed value, a second random number generator is
   used to create the seed values for the actual random number
   generator.
SEE ALSO
   krandom()
SOURCE
    void
    resetErnie(unsigned long seed)
    {
      unsigned long   rval;
      int             i, bit;
    
      pdebug(DFULL, "resetErnie\n");
      rval = seed;
      for (i = 0; i < 55; i++) {
        unsigned long   temp;
    
        for (bit = 0, temp = 0; bit < 32; bit++) {
          temp = temp << 1;
          rval = ((((rval >> 31) ^ (rval >> 6) ^ (rval >> 4) ^ (rval >> 2)
                    ^ (rval >> 1) ^ rval) & 0x1) << 31) | (rval >> 1);
          temp |= rval & 0x00000001;
        }
        Ran_tab[i] = temp;
      }
      Ran_k = 23;
      Ran_j = 54;
      for (i = 0; i < 18000; i++)
        krandom();
    }    

Util/round2

NAME
   round2 -- round a number to 2 decimal places.
SYNOPSIS
   double round2(double f)
NOTES
   Has most likely the same effect as ftrunc2(), so one of them
   can go.
SOURCE
    double
    round2(double f)
    {
      int             i;
    
      i = f * 100.0;
      f = i / 100.0;
      return f;
    }    

Util/saveRanTab

NAME
   saveRanTab -- save seed values to turn file
FUNCTION
   Save the table with seed values for the random number generator
   to the turn file.
SEE ALSO
   loadRanTab()
SOURCE
    void
    saveRanTab(FILE * f)
    {
      int             i;
    
      for (i = 0; i < RTAB_LENGTH; i++) {
        fprintf(f, "%u\n", Ran_tab[i]);
      }
    }    

Util/savefprintf

NAME
   savefprintf -- write to and and check if it was really written.
SYNOPSIS
   void savefprintf(FILE * f, char *format,...)
FUNCTION
   Writes data to file and checks if the write succeeded.
   If not the program is aborted.  This is primarily used
   to make sure the orders of players are really written to
   file.  There have been cases were a player got a reply 
   from the orders checker saying that their orders were valid,
   but when the turn ran there orders were no where to be found.    
NOTES
   The functions try to write to the log file... if a write to
   the orders file fails then a write to the log file is most
   likely to fail too.  Some other method of notifying the GM
   should be used.  

Util/send

NAME
   send -- send a group to a planet.
SYNOPSIS
   void send(group *g, planet *p)
INPUTS
   g -- group to send
   p -- destination planet
SOURCE
    void
    send(group *g, planet *p)
    {
      g->from = g->where;
      g->where = p;
      g->dist = dist(p, g->from);
    }    

Util/setproduction

NAME
   setproduction -- set production of a planet
SYNOPSIS
   void setproduction(planet *p, int t)
FUNCTION
   Set the production type of a planet. If the game option
   GAME_KEEPPRODUCTION is set, the production points spend
   on the previous product are preserved, otherwise all points
   are lost.
SOURCE
    void
    setproduction(game *aGame, planet *p, int t)
    {
      double          perccomp;
      double          mass;
      double          theshipmass;
      double          prog;
    
      if (p->producing == PR_SHIP) {
        theshipmass = typemass(p->producingshiptype);
        mass = theshipmass * INDPERSHIP;
        prog = p->inprogress;
        if (theshipmass > p->mat)
          mass += (theshipmass - p->mat) / p->resources;
        perccomp = prog / mass;
        p->mat += typemass(p->producingshiptype) * perccomp;
      }
      if (!(aGame->gameOptions & GAME_KEEPPRODUCTION))
        p->inprogress = 0;
      p->producing = t;
      p->producingshiptype = 0;
    }    

Util/shipmass

NAME
   shipmass -- compute the mass of a ship in a group of ships
SYNOPSIS
   double shipmass(group *g)
FUNCTION
   Compute the mass of a ship in a group of ships. This includes
   the mass of the cargo carried by the ship.
SEE ALSO
   typemass()
SOURCE
    double
    shipmass(group *g)
    {
      double          l;
      double          res;
    
      l = g->load;
      if (g->cargo)
        l /= g->cargo;
      res = typemass(g->type) + l;
      return res;
    }    

Util/ssystem

NAME
   ssystem -- run a dynamically created system command.
FUNCTION
   Construct a command using sprintf() and then run it using
   system().
NOTES
   Take care not to overflow the lineBuffer!
SOURCE
    int
    ssystem(char *format,...)
    {
      int             res;
      va_list         ap;
    
      va_start(ap, format);
      vsprintf(lineBuffer, format, ap);
      res = system(lineBuffer);
    
      if (res != 0) {
        plog(LBRIEF, "%s returned %d\n", lineBuffer, res);
      }
      else {
        plog(LPART, "ran %s\n", lineBuffer);
      }
      va_end(ap);
      return res;
    }    

Util/typeDefense

NAME
   typeDefense -- basic shield strength of a ship of type t
SYNOPSIS
   double typeDefense(shiptype *t)
FUNCTION
   The strength of the shields of a ship of type t. 
   This does not take in account the shield tech level.
   Basically the shield strength of a ship without cargo
   with all tech levels set 1.0.
SEE ALSO
   groupDefense()
SOURCE
    double
    typeDefense(shiptype *t)
    {
      double          res;
    
      res = t->shields * BATTLEMAGIC / pow(typemass(t), .333333333333333);
      return res;
    }    

Util/typeSpeed

NAME
   typeSpeed -- basic speed of a ship of type t
SYNOPSIS
   double typeSpeed(shiptype *t)
FUNCTION
   Compute the speed of a ship of type t. This does not take
   in account any of the techlevels or the cargo carried by
   a ship. 
SOURCE
    double
    typeSpeed(shiptype *t)
    {
      double          res;
    
      res = t->drive * DRIVEMAGIC / typemass(t);
      return res;
    }    

Util/typemass

NAME
   typemass -- compute mass of a ship type
SYNOPSIS
   double typemass(shiptype *t)
FUNCTION
   Compute mass of a ship type. This differs from the mass of a ship which
   includes the mass of the cargo carried by the ship.
SEE ALSO
   shipmass()
SOURCE
    double
    typemass(shiptype *t)
    {
      double          res;
    
      res = t->drive + weaponmass(t) + t->shields + t->cargo;
      return res;
    }    

Util/weaponmass

NAME
   weaponmass -- compute weapon mass of a ship type
SYNOPSIS
   double weaponmass(shiptype *t)
FUNCTION
   Compute the mass of the weapons of a ship type, this is a function of
   the weapon and the number of attacks.
SOURCE
    double
    weaponmass(shiptype *t)
    {
      double          res;
    
      res = (t->attacks ? t->weapons : 0) +
          ((t->attacks > 1) ? ((t->attacks - 1) * 0.5 * t->weapons) : 0);
      return res;
    }