]> git.pond.sub.org Git - empserver/blobdiff - src/util/fairland.c
Fix PRNG seeding to resist guessing
[empserver] / src / util / fairland.c
index d9630d2b90d7b4f0e433f6330fc17a81c5e17583..d95282f2c60e82ee872f093ba680e1dbe47ee670 100644 (file)
@@ -1,11 +1,11 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
+ *  Copyright (C) 1986-2013, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                Ken Stevens, Steve McClure, Markus Armbruster
  *
- *  This program is free software; you can redistribute it and/or modify
+ *  Empire is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
+ *  the Free Software Foundation, either version 3 of the License, or
  *  (at your option) any later version.
  *
  *  This program is distributed in the hope that it will be useful,
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  *  ---
  *
- *  See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
- *  related information and legal notices. It is expected that any future
- *  projects/authors will amend these files as needed.
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
  *
  *  ---
  *
  *  fairland.c: Create a nice, new world
- * 
+ *
  *  Known contributors to this file:
  *     Ken Stevens, 1995
  *     Steve McClure, 1998
+ *     Markus Armbruster, 2004-2012
  */
 
+#include <config.h>
+
 /* define ORE 1 to add resources, define ORE 0 if you want to use another
    program to add the resources */
-static int ORE  = 1;
+static int ORE = 1;
 static int quiet = 0;
 
 /* If you don't specify these command line arguments, then these are the
@@ -53,7 +55,7 @@ static int quiet = 0;
 #define FERT_MAX   56
 
 /* raise OIL_MAX for more oil */
-#define OIL_MAX    33
+#define OIL_MAX           33
 
 /* lower IRON_MIN for more iron */
 #define IRON_MIN   22
@@ -64,32 +66,30 @@ static int quiet = 0;
 /* lower URAN_MIN for more uranium */
 #define URAN_MIN   56
 
-#if defined(aix) || defined(linux) || defined(solaris)
-#include <unistd.h>
-#endif /* aix or linux */
-
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
 #include <stdio.h>
-#include <fcntl.h>
-#include "var.h"
-#include "misc.h"
-#include "power.h"
-#include "nat.h"
-#include "sect.h"
-#include "gamesdef.h"
+#include <unistd.h>
+#include "chance.h"
 #include "file.h"
-#include "xy.h"
 #include "optlist.h"
 #include "prototypes.h"
+#include "sect.h"
+#include "version.h"
+#include "xy.h"
 
 /* do not change these 4 defines */
-#define LANDMIN                1               /* plate altitude for normal land */
-#define HILLMIN                34              /* plate altitude for hills */
-#define PLATMIN                36              /* plate altitude for plateau */
-#define HIGHMIN                98              /* plate altitude for mountains */
+#define LANDMIN                1       /* plate altitude for normal land */
+#define HILLMIN                34      /* plate altitude for hills */
+#define PLATMIN                36      /* plate altitude for plateau */
+#define HIGHMIN                98      /* plate altitude for mountains */
 
-static void qprint _PROTO((const char *str));
+static void qprint(const char * const fmt, ...)
+    ATTRIBUTE((format (printf, 1, 2)));
 
-static const char *outfile = "newcap_script";
+#define DEFAULT_OUTFILE_NAME "newcap_script"
+static const char *outfile = DEFAULT_OUTFILE_NAME;
 /* mark the continents with a * so you can tell them
    from the islands 1 = mark, 0 = don't mark. */
 static int AIRPORT_MARKER = 0;
@@ -98,81 +98,76 @@ static int AIRPORT_MARKER = 0;
    1 = don't merge, 0 = merge. */
 static int DISTINCT_ISLANDS = 1;
 
-#define XSIZE           ((WORLD_X) / 2) /* basically world x-y size */
-#define YSIZE           (WORLD_Y)
-#define STABLE_CYCLE 4       /* stability required for perterbed capitals */
-#define INFINITY        999             /* a number which means "BIG" */
+static char *program_name;
+
+#define STABLE_CYCLE 4         /* stability required for perterbed capitals */
+#define INFINITY       999     /* a number which means "BIG" */
 
 /* these defines prevent infinite loops:
 */
 
-#define COAST_SEARCH_MAX 200  /* how many times do we look for a coast sector
-                               when growing continents and islands */
+#define COAST_SEARCH_MAX 200   /* how many times do we look for a coast sector
+                                  when growing continents and islands */
 #define DRIFT_BEFORE_CHECK ((WORLD_X + WORLD_Y)/2)
 #define DRIFT_MAX ((WORLD_X + WORLD_Y)*2)
-#define MOUNTAIN_SEARCH_MAX 1000 /* how long do we try to place mountains */
+#define MOUNTAIN_SEARCH_MAX 1000       /* how long do we try to place mountains */
 
 /* handy macros:
 */
 
 #define new_x(newx) (((newx) + WORLD_X) % WORLD_X)
 #define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y)
-#if !defined(_WIN32)
-#define max(a,b) (a>b?a:b)
-#endif
-#define rnd(x) (random() % (x))
-
-int secs;   /* number of sectors grown */
-int ctot;  /* total number of continents and islands grown */
-int *isecs; /* array of how large each island is */
-
-int nc, sc, di, sp, pm, ni, is, id; /* the 8 arguments to this program */
-int *capx, *capy;                   /* location of the nc capitals */
-int *mc, mcc;                       /* array and counter used for stability
-                                      check when perturbing */
-int spike;                          /* are we spiking? */
-int mind;                           /* the final distance between capitals that
-                                      we achieved */
-int dirx[] = {-2, -1, 1, 2, 1, -1}; /* gyujnb */
-int diry[] = {0, -1, -1, 0, 1, 1};
-
-int **own;                          /* owner of the sector.  -1 means water */
-int **elev;                         /* elevation of the sectors */
-int **sectx, **secty;               /* the sectors for each continent */
-int **sectc;                        /* which sectors are on the coast? */
-int *vector;                        /* used for measuring distances */
-int *weight;                        /* used for placing mountains */
-int *dsea, *dmoun;                  /* the dist to the ocean and mountain */
-int the_file;                     /* the file we write everything to */
-struct sctstr **sects;
-struct sctstr *sectsbuf;
-int fl_status;                      /* is anything wrong? */
-#define STATUS_NO_ROOM (1)          /* there was no room to grow */
-#define NUMTRIES 10                 /* keep trying to grow this many times */
-
-const char *numletter = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-
-void parse_args(int argc, char *argv[]);
-int allocate_memory(void);
-void init(void);
-int drift(void);
-void grow_continents(void);
-void create_elevations(void);
-void write_sects(void);
-int write_file(void);
-void output(void);
-int write_newcap_script(void);
-int stable(void);
-void elevate_land(void);
-void elevate_sea(void);
-void translate_continents(void);
-int map_symbol(int x, int y);
-static void fl_sct_init(coord x, coord y, s_char *ptr);
-
-void   print_vars();
-void   fl_move(int);
-void   next_coast();
-void   grow_islands();
+
+static int secs;               /* number of sectors grown */
+static int ctot;               /* total number of continents and islands grown */
+static int *isecs;             /* array of how large each island is */
+
+static int nc, sc, di, sp, pm, ni, is, id; /* the 8 args to this program */
+static unsigned long rnd_seed; /* optional seed argument */
+static int *capx, *capy;       /* location of the nc capitals */
+static int *mc, mcc;           /* array and counter used for stability
+                                  check when perturbing */
+static int spike;              /* are we spiking? */
+static int mind;               /* the final distance between capitals that
+                                  we achieved */
+static int dirx[] = { -2, -1, 1, 2, 1, -1 }; /* gyujnb */
+static int diry[] = { 0, -1, -1, 0, 1, 1 };
+
+static int **own;              /* owner of the sector.  -1 means water */
+static int **elev;             /* elevation of the sectors */
+static int **sectx, **secty;   /* the sectors for each continent */
+static int **sectc;            /* which sectors are on the coast? */
+static int *vector;            /* used for measuring distances */
+static int *weight;            /* used for placing mountains */
+static int *dsea, *dmoun;      /* the dist to the ocean and mountain */
+static int fl_status;          /* is anything wrong? */
+#define STATUS_NO_ROOM 1       /* there was no room to grow */
+#define NUMTRIES 10            /* keep trying to grow this many times */
+
+static const char *numletter =
+    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+static void help(char *);
+static void usage(void);
+static void parse_args(int argc, char *argv[]);
+static void allocate_memory(void);
+static void init(void);
+static int drift(void);
+static void grow_continents(void);
+static void create_elevations(void);
+static void write_sects(void);
+static void output(void);
+static int write_newcap_script(void);
+static int stable(void);
+static void elevate_land(void);
+static void elevate_sea(void);
+static int map_symbol(int x, int y);
+static void set_coastal_flags(void);
+
+static void print_vars(void);
+static void fl_move(int);
+static void next_coast(int c, int x, int y, int *xp, int *yp);
+static void grow_islands(void);
 
 /****************************************************************************
   MAIN
@@ -181,379 +176,402 @@ void    grow_islands();
 int
 main(int argc, char *argv[])
 {
-  int opt;
-  extern int optind;
-  extern char *optarg;
-  extern s_char *datadir;
-  char *config_file = NULL;
-  char tbuf[512];
-  int i = 0;
-
-#if !defined(_WIN32)
-  while ((opt = getopt(argc, argv, "ae:ioqs:")) != EOF) {
-    switch (opt) {
-    case 'a':
-      AIRPORT_MARKER = 1;
-      break;
-    case 'i':
-      DISTINCT_ISLANDS = 0;
-      break;
-    case 'e':
-      config_file = optarg;
-      break;
-    case 'o':
-      ORE = 0;
-      break;
-    case 'q':
-      quiet = 1;
-      break;
-    case 's':
-      outfile = optarg;
-      break;
+    int opt;
+    char *config_file = NULL;
+    int i = 0;
+    int seed_set = 0;
+
+    program_name = argv[0];
+    rnd_seed = 0;
+
+    while ((opt = getopt(argc, argv, "ae:hioqR:s:v")) != EOF) {
+       switch (opt) {
+       case 'a':
+           AIRPORT_MARKER = 1;
+           break;
+       case 'e':
+           config_file = optarg;
+           break;
+       case 'i':
+           DISTINCT_ISLANDS = 0;
+           break;
+       case 'o':
+           ORE = 0;
+           break;
+       case 'q':
+           quiet = 1;
+           break;
+       case 'R':
+           rnd_seed = strtoul(optarg, NULL, 10);
+           seed_set = 1;
+           break;
+       case 's':
+           outfile = optarg;
+           break;
+       case 'h':
+           usage();
+           exit(0);
+       case 'v':
+           printf("%s\n\n%s", version, legal);
+           exit(0);
+       default:
+           help(NULL);
+           exit(1);
+       }
     }
-  }
-#endif
-  if (config_file == NULL) {
-    sprintf (tbuf, "%s/econfig", datadir);
-    config_file = tbuf;
-  }
-  emp_config (config_file);
-
-#if !defined(_WIN32)
-  parse_args(argc - optind, argv + optind);
-#else
-  parse_args(argc - 1, argv + 1);
-#endif
-  if (allocate_memory() == -1)
-    exit(-1);
-  print_vars();
-  
-  do {
-    init();
-    if (!quiet && i)
-      printf("\ntry #%d (out of %d)...", i + 1, NUMTRIES);
-    qprint ("\n\n        #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
-    qprint ("placing capitals...\n");
-    if (!drift())
-    qprint ("fairland: unstable drift -- try increasisg DRIFT_MAX\n");
-    qprint ("growing continents...\n");
-    grow_continents();
-  } while (fl_status && ++i < NUMTRIES); 
-  if (fl_status) {
-         fputs("ERROR: World not large enough to hold continents\n", stderr);
-         exit(1);
-  }
-  qprint ("growing islands:");
-  grow_islands();
-  qprint ("\nelevating land...\n");
-  create_elevations();
-  qprint ("designating sectors...\n");
-  if (ORE)
-    qprint ("adding resources...\n");
-  write_sects();
-  qprint ("writing to sectors file...\n");
-  if (write_file() == -1)
-    exit (-1);
-  output();
-  write_newcap_script();
-  exit(0);
+    parse_args(argc - optind, argv + optind);
+
+    if (!seed_set)
+       rnd_seed = pick_seed();
+    seed_prng(rnd_seed);
+    empfile_init();
+    if (emp_config(config_file) < 0)
+       exit(1);
+    empfile_fixup();
+
+    allocate_memory();
+    print_vars();
+
+    do {
+       init();
+       if (i)
+           qprint("\ntry #%d (out of %d)...", i + 1, NUMTRIES);
+       qprint("\n\n        #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
+       qprint("seed is %lu\n", rnd_seed);
+       qprint("placing capitals...\n");
+       if (!drift())
+           qprint("fairland: unstable drift -- try increasisg DRIFT_MAX\n");
+       qprint("growing continents...\n");
+       grow_continents();
+    } while (fl_status && ++i < NUMTRIES);
+    if (fl_status) {
+       fputs("ERROR: World not large enough to hold continents\n",
+             stderr);
+       exit(1);
+    }
+    qprint("growing islands:");
+    grow_islands();
+    qprint("\nelevating land...\n");
+    create_elevations();
+    qprint("designating sectors...\n");
+    if (ORE)
+       qprint("adding resources...\n");
+    write_newcap_script();
+
+    if (chdir(gamedir)) {
+       fprintf(stderr, "Can't chdir to %s (%s)\n", gamedir, strerror(errno));
+       exit(EXIT_FAILURE);
+    }
+    if (!ef_open(EF_SECTOR, EFF_MEM | EFF_NOTIME))
+       exit(1);
+    write_sects();
+    qprint("writing to sectors file...\n");
+    if (!ef_close(EF_SECTOR))
+       exit(1);
+
+    output();
+    qprint("\n\nA script for adding all the countries can be found in \"%s\".\n",
+          outfile);
+    if (!ORE)
+       qprint("\t*** Resources have not been added ***\n");
+    exit(0);
 }
 
-void
-print_vars()
+static void
+print_vars(void)
 {
-  if (quiet)
-      return;
-  puts("Creating a planet with:\n");
-  printf("%d continents\n", nc);
-  printf("continent size: %d\n", sc);
-  printf("number of islands: %d\n", ni);
-  printf("average size of islands: %d\n", is);
-  printf("spike: %d%%\n", sp);
-  printf("%d%% of land is mountain (each continent will have %d mountains)\n",
-        pm, (pm*sc)/100);
-  printf("minimum distance between continents: %d\n", di);
-  printf("minimum distance from islands to continents: %d\n", id);
-  printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
+    if (quiet)
+       return;
+    puts("Creating a planet with:\n");
+    printf("%d continents\n", nc);
+    printf("continent size: %d\n", sc);
+    printf("number of islands: %d\n", ni);
+    printf("average size of islands: %d\n", is);
+    printf("spike: %d%%\n", sp);
+    printf("%d%% of land is mountain (each continent will have %d mountains)\n",
+          pm, (pm * sc) / 100);
+    printf("minimum distance between continents: %d\n", di);
+    printf("minimum distance from islands to continents: %d\n", id);
+    printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
 }
 
-int
-my_sqrt(n)
-int n;     
+static int
+my_sqrt(int n)
 {
-  int i;
+    int i;
 
-  for (i = 1; i*i < n*10000; ++i);
-  return (i+50)/100;
+    for (i = 1; i * i < n * 10000; ++i) ;
+    return (i + 50) / 100;
 }
 
 /****************************************************************************
   PARSE COMMAND LINE ARGUMENTS
 ****************************************************************************/
 
-void
+static void
+help(char *complaint)
+{
+    if (complaint)
+       fprintf(stderr, "%s: %s\n", program_name, complaint);
+    fprintf(stderr, "Try -h for help.\n");
+}
+
+static void
+usage(void)
+{
+    printf("Usage: %s [OPTION]... NC SC [NI] [IS] [SP] [PM] [DI] [ID]\n"
+          "  -a              airport marker for continents\n"
+          "  -e CONFIG-FILE  configuration file\n"
+          "                  (default %s)\n"
+          "  -h              display this help and exit\n"
+          "  -i              islands may merge\n"
+          "  -o              don't set resources\n"
+          "  -q              quiet\n"
+          "  -R SEED         seed for random number generator\n"
+          "  -s SCRIPT       name of script to create (default %s)\n"
+          "  NC              number of continents\n"
+          "  SC              continent size\n"
+          "  NI              number of islands (default NC)\n"
+          "  IS              average island size (default SC/2)\n"
+          "  SP              spike percentage: 0 = round, 100 = snake (default %d)\n"
+          "  PM              percentage of land that is mountain (default %d)\n"
+          "  DI              minimum distance between continents (default %d)\n"
+          "  ID              minimum distance from islands to continents (default %d)\n",
+          program_name, dflt_econfig, DEFAULT_OUTFILE_NAME,
+          DEFAULT_SPIKE, DEFAULT_MOUNTAIN, DEFAULT_CONTDIST, DEFAULT_ISLDIST);
+}
+
+static void
 parse_args(int argc, char *argv[])
 {
-  if (argc < 2 || argc > 8) {
-    puts("fairland syntax:\n");
-    puts("fairland [-e config] [-aiqo] [-s script] <nc> <sc> [<ni>] [<is>] [<sp>] [<pm>] [<di>] [<id>]");
-    puts ("-q = quiet, -o = no ore produced");
-    puts ("-a = Airport marker for continents, -i = islands not distinct");
-    printf ("-e = read config file, -s = name of script (default %s)\n",
-           outfile);
-    puts("nc = number of continents [MANDATORY]");
-    puts("sc = continent size [MANDATORY]");
-    puts("ni = number of islands (default = nc)");
-    puts("is = average size of islands (default = sc/2)");
-    printf("sp = spike percentage: 0 = round, 100 = snake (default = %d)\n", DEFAULT_SPIKE);
-    printf("pm = the percentage of land that is mountain (default = %d)\n", DEFAULT_MOUNTAIN);
-    printf("di = the minimum distance between continents (default = %d)\n", DEFAULT_CONTDIST);
-    printf("id = minimum distance from islands to continents (default = %d)\n", DEFAULT_ISLDIST);
-    exit (1);
-  }
-  nc = atoi(argv[0]);
-  if (nc < 1) {
-    puts("fairland: error -- number of continents must be > 0");
-    exit (1);
-  }
-
-  sc = atoi(argv[1]);
-  if (sc < 1) {
-    puts("fairland: error -- size of continents must be > 0");
-    exit (1);
-  }
-
-  if (argc > 2)
-    ni = atoi(argv[2]);
-  else
-    ni = nc;
-
-  if (argc > 3)
-    is = atoi(argv[3]);
-  else
-    is = sc/2;
-  if (is < 0)
-    is = 0;
-
-  if (argc > 4)
-    sp = atoi(argv[4]);
-  else
-    sp = DEFAULT_SPIKE;
-  if (sp < 0)
-    sp = 0;
-  if (sp > 100)
-    sp = 100;
-
-  if (argc > 5)
-    pm = atoi(argv[5]);
-  else
-    pm = DEFAULT_MOUNTAIN;
-  if (pm < 0)
-    pm = 0;
-
-  if (argc > 6)
-    di = atoi(argv[6]);
-  else
-    di = DEFAULT_CONTDIST;
-
-  if (di < 0) {
-    puts("fairland: error -- distance between continents must be >= 0");
-    exit (1);
-  }
-  if (di > WORLD_X/2 || di > WORLD_Y/2) {
-    puts("fairland: error -- distance between continents too large");
-    exit (1);
-  }
-
-  if (argc > 7)
-    id = atoi(argv[7]);
-  else
-    id = DEFAULT_ISLDIST;
-  if (id < 0) {
-    puts("fairland: error -- distance from islands to continents must be >= 0");
-    exit (1);
-  }
-  if (id > WORLD_X || id > WORLD_Y) {
-    puts("fairland: error -- distance from islands to continents too large");
-    exit (1);
-  }
-  if (nc*sc + nc*my_sqrt(sc)*2*(di+1) > WORLD_X * WORLD_Y) {
-    puts("fairland: error -- world not big enough to fit continents.");
-    puts("arguments must satisfy:");
-    puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
-    exit (1);
-  }
+    if (argc < 2) {
+       help("missing arguments");
+       exit(1);
+    }
+    if (argc > 8) {
+       help("too many arguments");
+       exit(1);
+    }
+    nc = atoi(argv[0]);
+    if (nc < 1) {
+       puts("fairland: error -- number of continents must be > 0");
+       exit(1);
+    }
+
+    sc = atoi(argv[1]);
+    if (sc < 1) {
+       puts("fairland: error -- size of continents must be > 0");
+       exit(1);
+    }
+
+    if (argc > 2)
+       ni = atoi(argv[2]);
+    else
+       ni = nc;
+
+    if (argc > 3)
+       is = atoi(argv[3]);
+    else
+       is = sc / 2;
+    if (is < 1)
+       is = 1;
+
+    if (argc > 4)
+       sp = atoi(argv[4]);
+    else
+       sp = DEFAULT_SPIKE;
+    if (sp < 0)
+       sp = 0;
+    if (sp > 100)
+       sp = 100;
+
+    if (argc > 5)
+       pm = atoi(argv[5]);
+    else
+       pm = DEFAULT_MOUNTAIN;
+    if (pm < 0)
+       pm = 0;
+
+    if (argc > 6)
+       di = atoi(argv[6]);
+    else
+       di = DEFAULT_CONTDIST;
+
+    if (di < 0) {
+       puts("fairland: error -- distance between continents must be >= 0");
+       exit(1);
+    }
+    if (di > WORLD_X / 2 || di > WORLD_Y / 2) {
+       puts("fairland: error -- distance between continents too large");
+       exit(1);
+    }
+
+    if (argc > 7)
+       id = atoi(argv[7]);
+    else
+       id = DEFAULT_ISLDIST;
+    if (id < 0) {
+       puts("fairland: error -- distance from islands to continents must be >= 0");
+       exit(1);
+    }
+    if (id > WORLD_X || id > WORLD_Y) {
+       puts("fairland: error -- distance from islands to continents too large");
+       exit(1);
+    }
+    if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
+       puts("fairland: warning -- world might be too small to fit continents.");
+       puts("arguments should satisfy:");
+       puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
+    }
 }
 
 /****************************************************************************
   VARIABLE INITIALIZATION
 ****************************************************************************/
 
-int
+static void
 allocate_memory(void)
 {
-  int i;
-  time_t now;
-
-#if !defined(_WIN32)
-  the_file = open(empfile[EF_SECTOR].file, O_RDWR|O_CREAT|O_TRUNC, 0660);
-#else
-  the_file = open(empfile[EF_SECTOR].file, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0660);
-#endif
-  if (the_file < 0) {
-    perror(empfile[EF_SECTOR].file);
-    return -1;
-  }
-  sectsbuf = (struct sctstr *)calloc((YSIZE * XSIZE), sizeof(struct sctstr));
-  sects = (struct sctstr **)calloc(YSIZE, sizeof(struct sctstr *));
-  for (i = 0; i < YSIZE; i++)
-    sects[i] = &sectsbuf[XSIZE * i];
-  time(&now);
-#if !defined(_WIN32)
-  srandom(now+getpid());
-#else
-  srandom(now);
-#endif
-  capx = (int *)calloc(nc, sizeof(int));
-  capy = (int *)calloc(nc, sizeof(int));
-  vector = (int *)calloc(WORLD_X+WORLD_Y, sizeof(int));
-  mc = (int *)calloc(STABLE_CYCLE, sizeof(int));
-  own = (int **)calloc(WORLD_X, sizeof(int*));
-  elev = (int **)calloc(WORLD_X, sizeof(int*));
-  for (i = 0; i < WORLD_X; ++i) {
-    own[i] = (int *)calloc(WORLD_Y, sizeof(int));
-    elev[i] = (int *)calloc(WORLD_Y, sizeof(int));
-  }
-  sectx = (int **)calloc(nc+ni, sizeof(int*));
-  secty = (int **)calloc(nc+ni, sizeof(int*));
-  sectc = (int **)calloc(nc+ni, sizeof(int*));
-  isecs = (int *)calloc(nc+ni, sizeof(int));
-  weight = (int *)calloc(max(sc,is*2), sizeof(int));
-  dsea = (int *)calloc(max(sc,is*2), sizeof(int));
-  dmoun = (int *)calloc(max(sc,is*2), sizeof(int));
-  for (i = 0; i < nc; ++i) {
-    sectx[i] = (int *)calloc(sc, sizeof(int));
-    secty[i] = (int *)calloc(sc, sizeof(int));
-    sectc[i] = (int *)calloc(sc, sizeof(int));
-  }
-  for (i = nc; i < nc+ni; ++i) {
-    sectx[i] = (int *)calloc(is*2, sizeof(int));
-    secty[i] = (int *)calloc(is*2, sizeof(int));
-    sectc[i] = (int *)calloc(is*2, sizeof(int));
-  }
-
-  return 0;
+    int i;
+
+    capx = calloc(nc, sizeof(int));
+    capy = calloc(nc, sizeof(int));
+    vector = calloc(WORLD_X + WORLD_Y, sizeof(int));
+    mc = calloc(STABLE_CYCLE, sizeof(int));
+    own = calloc(WORLD_X, sizeof(int *));
+    elev = calloc(WORLD_X, sizeof(int *));
+    for (i = 0; i < WORLD_X; ++i) {
+       own[i] = calloc(WORLD_Y, sizeof(int));
+       elev[i] = calloc(WORLD_Y, sizeof(int));
+    }
+    sectx = calloc(nc + ni, sizeof(int *));
+    secty = calloc(nc + ni, sizeof(int *));
+    sectc = calloc(nc + ni, sizeof(int *));
+    isecs = calloc(nc + ni, sizeof(int));
+    weight = calloc(MAX(sc, is * 2), sizeof(int));
+    dsea = calloc(MAX(sc, is * 2), sizeof(int));
+    dmoun = calloc(MAX(sc, is * 2), sizeof(int));
+    for (i = 0; i < nc; ++i) {
+       sectx[i] = calloc(sc, sizeof(int));
+       secty[i] = calloc(sc, sizeof(int));
+       sectc[i] = calloc(sc, sizeof(int));
+    }
+    for (i = nc; i < nc + ni; ++i) {
+       sectx[i] = calloc(is * 2, sizeof(int));
+       secty[i] = calloc(is * 2, sizeof(int));
+       sectc[i] = calloc(is * 2, sizeof(int));
+    }
+
 }
 
-void
+static void
 init(void)
 {
-  int i, j, xx = 0, yy = 0;
+    int i, j, xx = 0, yy = 0;
 
-  mcc = 0;
-  fl_status = 0;
+    mcc = 0;
+    fl_status = 0;
 
-  for (i = 0; i < WORLD_X; ++i) {
-    for (j = 0; j < WORLD_Y; ++j) {
-      own[i][j] = -1;
-      elev[i][j] = -INFINITY;
+    for (i = 0; i < WORLD_X; ++i) {
+       for (j = 0; j < WORLD_Y; ++j) {
+           own[i][j] = -1;
+           elev[i][j] = -INFINITY;
+       }
     }
-  }
-
-  for (i = 0; i < nc; ++i, xx += 2) {
-    if (xx >= WORLD_X) {
-      ++yy;
-      xx = yy%2;
-      if (yy == WORLD_Y) {
-       puts("fairland error: world not big enough for all the continents.\n");
-       exit(1);
-      }
+
+    for (i = 0; i < nc; ++i) {
+       if (xx >= WORLD_X) {
+           ++yy;
+           xx = yy % 2;
+           if (yy == WORLD_Y) {
+               puts("fairland error: world not big enough for all the continents.\n");
+               exit(1);
+           }
+       }
+       capx[i] = xx;
+       capy[i] = yy;
+       xx += 2;
     }
-    capx[i] = xx;
-    capy[i] = yy;
-  }
-  for (i = 0; i < STABLE_CYCLE; ++i)
-    mc[i] = i;
+    for (i = 0; i < STABLE_CYCLE; ++i)
+       mc[i] = i;
 }
-  
+
 /****************************************************************************
   DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
 ****************************************************************************/
 
 /* How isolated is capital j?
 */
-int
-iso(j, newx, newy)
-int j, newx, newy;
+static int
+iso(int j, int newx, int newy)
 {
-  int i, md, d = WORLD_X + WORLD_Y;
-  
-  for (i = 0; i < nc; ++i) {
-    if (i == j)
-      continue;
-    md = mapdist(capx[i], capy[i], newx, newy);
-    if (md < d)
-      d = md;
-  }
-
-  return d;
+    int i, md, d = WORLD_X + WORLD_Y;
+
+    for (i = 0; i < nc; ++i) {
+       if (i == j)
+           continue;
+       md = mapdist(capx[i], capy[i], newx, newy);
+       if (md < d)
+           d = md;
+    }
+
+    return d;
 }
 
 /* Drift all the capitals
 */
-int
+static int
 drift(void)
 {
-  int i, turns;
-  
-  for (turns = 0; turns < DRIFT_MAX; ++turns) {
-    if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
-      return 1;
-    for (i = 0; i < nc; ++i)
-      fl_move(i);
-  }
-  return 0;
+    int i, turns;
+
+    for (turns = 0; turns < DRIFT_MAX; ++turns) {
+       if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
+           return 1;
+       for (i = 0; i < nc; ++i)
+           fl_move(i);
+    }
+    return 0;
 }
 
 /* Check to see if we have stabilized--can we stop drifting the capitals?
 */
 
-int
+static int
 stable(void)
 {
-  int i, isod, d = 0, stab = 1;
-
-  for (i = 0; i < nc; ++i) {
-    isod = iso(i, capx[i], capy[i]);
-    if (isod > d)
-      d = isod;
-  }
-  for (i = 0; i < STABLE_CYCLE; ++i)
-    if (d != mc[i])
-      stab = 0;
-  mc[mcc] = d;
-  mcc = (mcc + 1) % STABLE_CYCLE;
-  return stab?d:0;
+    int i, isod, d = 0, stab = 1;
+
+    for (i = 0; i < nc; ++i) {
+       isod = iso(i, capx[i], capy[i]);
+       if (isod > d)
+           d = isod;
+    }
+    for (i = 0; i < STABLE_CYCLE; ++i)
+       if (d != mc[i])
+           stab = 0;
+    mc[mcc] = d;
+    mcc = (mcc + 1) % STABLE_CYCLE;
+    return stab ? d : 0;
 }
 
 /* This routine does the actual drifting
 */
 
-void
-fl_move(j)
-int j;
+static void
+fl_move(int j)
 {
-  int i, n, newx, newy;
-
-  for (i = rnd(6), n = 0; n < 6; i = (i + 1)%6, ++n) {
-    newx = new_x(capx[j] + dirx[i]);
-    newy = new_y(capy[j] + diry[i]);
-    if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
-      capx[j] = newx;
-      capy[j] = newy;
-      return;
+    int i, n, newx, newy;
+
+    for (i = roll0(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
+       newx = new_x(capx[j] + dirx[i]);
+       newy = new_y(capy[j] + diry[i]);
+       if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
+           capx[j] = newx;
+           capy[j] = newy;
+           return;
+       }
     }
-  }
 }
 
 /****************************************************************************
@@ -563,201 +581,192 @@ int j;
 /* Look for a coastal sector of continent c
 */
 
-void
-find_coast(c)
-int c;
+static void
+find_coast(int c)
 {
-  int i, j;
-  
-  for (i = 0; i < secs; ++i) {
-    sectc[c][i] = 0;
-    for (j = 0; j < 6; ++j)
-      if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
-       sectc[c][i] = 1;
-  }
+    int i, j;
+
+    for (i = 0; i < secs; ++i) {
+       sectc[c][i] = 0;
+       for (j = 0; j < 6; ++j)
+           if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
+               sectc[c][i] = 1;
+    }
 }
 
 /* Used for measuring distances
 */
-int
-next_vector(n)
-int n;
+static int
+next_vector(int n)
 {
-  int i;
-
-  if (n == 1) {
-    vector[0] += 1;
-    vector[0] %= 6;
-    return vector[0];
-  }
-  for (i = 1; i < n && vector[i] == vector[i-1]; ++i);
-  vector[i-1] += 1;
-  vector[i-1] %= 6;
-  return i > 1 || vector[0] > 0;
+    int i;
+
+    if (n == 1) {
+       vector[0] += 1;
+       vector[0] %= 6;
+       return vector[0];
+    }
+    for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
+    vector[i - 1] += 1;
+    vector[i - 1] %= 6;
+    return i > 1 || vector[0] > 0;
 }
 
 /* Test to see if we're allowed to grow there: the arguments di and id
 */
-int
-try_to_grow(c, newx, newy, d)
-int c, newx, newy, d;
+static int
+try_to_grow(int c, int newx, int newy, int d)
 {
-  int i, j, px, py;
-
-  for (i = 1; i <= d; ++i) {
-    for (j = 0; j < i; ++j)
-      vector[j] = 0;
-    do {
-      px = newx;
-      py = newy;
-      for (j = 0; j < i; ++j) {
-       px = new_x(px + dirx[vector[j]]);
-       py = new_y(py + diry[vector[j]]);
-      }
-      if (own[px][py] != -1 &&
-         own[px][py] != c &&
-         (DISTINCT_ISLANDS || own[px][py] < nc))
-       return 0;
-    } while (next_vector(i));
-  }
-  sectx[c][secs] = newx;
-  secty[c][secs] = newy;
-  own[newx][newy] = c;
-  return 1;
+    int i, j, px, py;
+
+    for (i = 1; i <= d; ++i) {
+       for (j = 0; j < i; ++j)
+           vector[j] = 0;
+       do {
+           px = newx;
+           py = newy;
+           for (j = 0; j < i; ++j) {
+               px = new_x(px + dirx[vector[j]]);
+               py = new_y(py + diry[vector[j]]);
+           }
+           if (own[px][py] != -1 &&
+               own[px][py] != c &&
+               (DISTINCT_ISLANDS || own[px][py] < nc))
+               return 0;
+       } while (next_vector(i));
+    }
+    sectx[c][secs] = newx;
+    secty[c][secs] = newy;
+    own[newx][newy] = c;
+    return 1;
 }
 
 /* Move along the coast in a clockwise direction.
 */
 
-void
-next_coast(c, x, y, xp, yp)
-int c, x, y, *xp, *yp;
+static void
+next_coast(int c, int x, int y, int *xp, int *yp)
 {
-  int i, nx, ny, wat = 0;
-
-  if (secs == 1) {
-    *xp = x;
-    *yp = y;
-    return;
-  }
-
-  for (i = 0; i < 12; ++i) {
-    nx = new_x(x+dirx[i%6]);
-    ny = new_y(y+diry[i%6]);
-    if (own[nx][ny] == -1)
-      wat = 1;
-    if (wat && own[nx][ny] == c) {
-      *xp = nx;
-      *yp = ny;
-      return;
+    int i, nx, ny, wat = 0;
+
+    if (secs == 1) {
+       *xp = x;
+       *yp = y;
+       return;
+    }
+
+    for (i = 0; i < 12; ++i) {
+       nx = new_x(x + dirx[i % 6]);
+       ny = new_y(y + diry[i % 6]);
+       if (own[nx][ny] == -1)
+           wat = 1;
+       if (wat && own[nx][ny] == c) {
+           *xp = nx;
+           *yp = ny;
+           return;
+       }
     }
-  }
 }
 
 /* Choose a sector to grow from
 */
 
-int
+static int
 new_try(int c)
 {
-  int i, starti;
-
-  if (secs == 1) {
-    if (sectc[c][0])
-      return 0;
-  }
-  else {
-    i = starti = (spike && sectc[c][secs-1])?secs-1:rnd(secs);
-    do {
-      if (sectc[c][i])
-       return i;
-      i = (i + 1)%secs;
-    } while (i != starti);
-    if (c < nc) {
-      printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n", c + 'a', secs);
-      exit (1);
+    int i, starti;
+
+    if (secs == 1) {
+       if (sectc[c][0])
+           return 0;
+    } else {
+       i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : roll0(secs);
+       do {
+           if (sectc[c][i])
+               return i;
+           i = (i + 1) % secs;
+       } while (i != starti);
+       assert(c >= nc);
+       return -1;
     }
-    else
-      return -1;
-  }
-  return -1;
+    return -1;
 }
 
 /* Grow continent c by 1 sector
 */
 
-int
-grow_one_sector(c)
-int c;
+static int
+grow_one_sector(int c)
 {
-  int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
+    int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
 
-  spike = rnd(100) < sp;
-  if ((try1 = new_try(c)) == -1)
-    return 0;
-  x = sx = sectx[c][try1];
-  y = sy = secty[c][try1];
-  coast_search = 0;
-  done = 0;
-  do {
-    if (spike) {
-      for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1)%6, ++n) {
-       newx = new_x(x+dirx[i]);
-       newy = new_y(y+diry[i]);
-       if (own[newx][newy] == -1 &&
-           (n > 5 ||
-            (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
-             own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
-         if (try_to_grow(c, newx, newy, c<nc?di:id))
-           done = 1;
-      }
+    spike = roll0(100) < sp;
+    if ((try1 = new_try(c)) == -1)
+       return 0;
+    x = sx = sectx[c][try1];
+    y = sy = secty[c][try1];
+    coast_search = 0;
+    done = 0;
+    do {
+       if (spike) {
+           for (i = roll0(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
+               newx = new_x(x + dirx[i]);
+               newy = new_y(y + diry[i]);
+               if (own[newx][newy] == -1 &&
+                   (n > 5 ||
+                    (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
+                     own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
+                   if (try_to_grow(c, newx, newy, c < nc ? di : id))
+                       done = 1;
+           }
+       } else
+           for (i = roll0(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
+               newx = new_x(x + dirx[i]);
+               newy = new_y(y + diry[i]);
+               if (own[newx][newy] == -1)
+                   if (try_to_grow(c, newx, newy, c < nc ? di : id))
+                       done = 1;
+           }
+       next_coast(c, x, y, &x, &y);
+       ++coast_search;
+    } while (!done && coast_search < COAST_SEARCH_MAX &&
+            (secs == 1 || x != sx || y != sy));
+    if (!done && c < nc) {
+       qprint("fairland: error -- continent %c had no room to grow!\n",
+              numletter[c % 62]);
+       fl_status |= STATUS_NO_ROOM;
     }
-    else
-      for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1)%6, ++n) {
-       newx = new_x(x+dirx[i]);
-       newy = new_y(y+diry[i]);
-       if (own[newx][newy] == -1)
-         if (try_to_grow(c, newx, newy, c<nc?di:id))
-           done = 1;
-      }
-    next_coast(c, x, y, &x, &y);
-    ++coast_search;
-  } while (!done && coast_search < COAST_SEARCH_MAX &&
-          (secs == 1 || x != sx || y != sy));
-  if (!done && c < nc) {
-    if (!quiet)
-      printf("fairland: error -- continent %c had no room to grow!\n",
-             numletter[c % 62]);
-    fl_status |= STATUS_NO_ROOM;
-  }
-  return done;
+    return done;
 }
 
 /* Grow all the continents
 */
-void
+static void
 grow_continents(void)
 {
-  int c;
-
-  for (c = 0; c < nc; ++c) {
-    sectx[c][0] = capx[c];
-    secty[c][0] = capy[c];
-    own[sectx[c][0]][secty[c][0]] = c;
-    sectx[c][1] = new_x(capx[c] + 2);
-    secty[c][1] = capy[c];
-    own[sectx[c][1]][secty[c][1]] = c;
-  }
-
-  for (secs = 2; secs < sc && !fl_status; ++secs) {
+    int c;
+
     for (c = 0; c < nc; ++c) {
-      find_coast(c);
-      grow_one_sector(c);
+       sectx[c][0] = capx[c];
+       secty[c][0] = capy[c];
+       own[sectx[c][0]][secty[c][0]] = c;
+       sectx[c][1] = new_x(capx[c] + 2);
+       secty[c][1] = capy[c];
+       own[sectx[c][1]][secty[c][1]] = c;
     }
-  }
-  if (fl_status && !quiet)
-    printf("Only managed to grow %d out of %d sectors.\n", secs, sc);
-  ctot = nc;
+
+    for (secs = 2; secs < sc && !fl_status; ++secs) {
+       for (c = 0; c < nc; ++c) {
+           find_coast(c);
+           grow_one_sector(c);
+       }
+    }
+    for (c = 0; c < nc; ++c)
+       find_coast(c);
+
+    if (fl_status)
+       qprint("Only managed to grow %d out of %d sectors.\n", secs, sc);
+    ctot = nc;
 }
 
 /****************************************************************************
@@ -766,103 +775,102 @@ grow_continents(void)
 
 /* Choose a place to start growing an island from
 */
-int
-place_island(c, xp, yp)
-int c, *xp, *yp;
+static int
+place_island(int c, int *xp, int *yp)
 {
-  int d, sx, sy;
-  int ssy = rnd(WORLD_Y);
-  int ssx = new_x(rnd(WORLD_X/2)*2 + ssy%2);
-
-  if (ssx > WORLD_X - 2)
-    ssx = new_x(ssx + 2);
-  for (d = di + id; d >= id; --d) {
-    sx = ssx;
-    sy = ssy;
-    *xp = new_x(sx + 2);
-    for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
-      if (*xp >= WORLD_X) {
-       *yp = new_y(*yp + 1);
-       *xp = (*yp)%2;
-       if (*xp == sx && *yp == sy)
-         break;
-      }
-      if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
-       return 1;
+    int d, sx, sy;
+    int ssy = roll0(WORLD_Y);
+    int ssx = new_x(roll0(WORLD_X / 2) * 2 + ssy % 2);
+
+    if (ssx > WORLD_X - 2)
+       ssx = new_x(ssx + 2);
+    for (d = di + id; d >= id; --d) {
+       sx = ssx;
+       sy = ssy;
+       *xp = new_x(sx + 2);
+       for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
+           if (*xp >= WORLD_X) {
+               *yp = new_y(*yp + 1);
+               *xp = *yp % 2;
+               if (*xp == sx && *yp == sy)
+                   break;
+           }
+           if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
+               return 1;
+       }
     }
-  }
-  return 0;
+    return 0;
 }
 
 /* Grow all the islands
 */
 
-void
-grow_islands()
+static void
+grow_islands(void)
 {
-  int c, x, y, isiz;
-
-  for (c = nc; c < nc+ni; ++c) {
-    secs = 0;
-    if (!place_island(c, &x, &y))
-      return;
-    isiz = 1 + rnd(2*is - 1);
-    do {
-      ++secs;
-      find_coast(c);
-      } while (secs < isiz && grow_one_sector(c));
-    if (quiet == 0) printf(" %d(%d)", c - nc + 1, secs);
-    isecs[c] = secs;
-    ctot = c;
-  }
+    int c, x, y, isiz;
+
+    for (c = nc; c < nc + ni; ++c) {
+       secs = 0;
+       if (!place_island(c, &x, &y))
+           return;
+       isiz = roll(2 * is - 1);
+       do {
+           ++secs;
+           find_coast(c);
+       } while (secs < isiz && grow_one_sector(c));
+       find_coast(c);
+       qprint(" %d(%d)", c - nc + 1, secs);
+       isecs[c] = secs;
+       ctot++;
+    }
 }
 
 /****************************************************************************
   CREATE ELEVATIONS
 ****************************************************************************/
-void
+static void
 create_elevations(void)
 {
-  elevate_land();
-  elevate_sea();
+    elevate_land();
+    elevate_sea();
 }
 
 /* Generic function for finding the distance to the closest sea, land, or
    mountain
 */
-int
-distance_to_what(x,y,flag)
-int x, y, flag;
+static int
+distance_to_what(int x, int y, int flag)
 {
-  int j, d, px, py;
-
-  for (d = 1; d < 5; ++d) {
-    for (j = 0; j < d; ++j)
-      vector[j] = 0;
-    do {
-      px = x;
-      py = y;
-      for (j = 0; j < d; ++j) {
-       px = new_x(px + dirx[vector[j]]);
-       py = new_y(py + diry[vector[j]]);
-      }
-      switch(flag) {
-      case 0: /* distance to sea */
-       if (own[px][py] == -1)
-         return d;
-       break;
-      case 1: /* distance to land */
-       if (own[px][py] != -1)
-         return d;
-       break;
-      case 2: /* distance to mountain */
-       if (elev[px][py] == INFINITY)
-         return d;
-       break;
-      }
-    } while (next_vector(d));
-  }
-  return d;
+    int j, d, px, py;
+
+    for (d = 1; d < 5; ++d) {
+       for (j = 0; j < d; ++j)
+           vector[j] = 0;
+       do {
+           px = x;
+           py = y;
+           for (j = 0; j < d; ++j) {
+               px = new_x(px + dirx[vector[j]]);
+               py = new_y(py + diry[vector[j]]);
+           }
+           switch (flag) {
+           case 0:             /* distance to sea */
+               if (own[px][py] == -1)
+                   return d;
+               break;
+           case 1:             /* distance to land */
+               if (own[px][py] != -1)
+                   return d;
+               break;
+           case 2:             /* distance to mountain */
+               if (elev[px][py] == INFINITY)
+                   return d;
+               break;
+           }
+       } while (next_vector(d));
+    }
+    return d;
 }
 
 #define ELEV elev[sectx[c][i]][secty[c][i]]
@@ -871,382 +879,321 @@ int x, y, flag;
 
 /* Decide where the mountains go
 */
-void
+static void
 elevate_land(void)
 {
-  int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk, r, dk;
+    int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
+       r, dk;
 
-  for (c = 0; c < ctot; ++c) {
-    total = 0;
-    ns = (c < nc)?sc:isecs[c];
-    nm = (pm*ns)/100;
+    for (c = 0; c < ctot; ++c) {
+       total = 0;
+       ns = (c < nc) ? sc : isecs[c];
+       nm = (pm * ns) / 100;
 
 /* Place the mountains */
 
-    for (i = 0; i < ns; ++i) {
-      dsea[i] = distance_to_sea();
-      weight[i] = (total += (dsea[i]*dsea[i]));
-    }
-    
-    for (k = nm, mountain_search = 0;
-        k && mountain_search < MOUNTAIN_SEARCH_MAX;
-        ++mountain_search) {
-      r = rnd(total);
-      for (i = 0; i < ns; ++i)
-       if (r < weight[i] && ELEV == -INFINITY && (c >= nc || 
-           ((!(capx[c] == sectx[c][i] && capy[c] == secty[c][i])) &&
-            (!(new_x(capx[c] + 2) == sectx[c][i] && capy[c] == secty[c][i]))))) {
-         ELEV = INFINITY;
-         break;
+       for (i = 0; i < ns; ++i) {
+           dsea[i] = distance_to_sea();
+           weight[i] = (total += (dsea[i] * dsea[i]));
+       }
+
+       for (k = nm, mountain_search = 0;
+            k && mountain_search < MOUNTAIN_SEARCH_MAX;
+            ++mountain_search) {
+           r = roll0(total);
+           for (i = 0; i < ns; ++i)
+               if (r < weight[i] && ELEV == -INFINITY &&
+                   (c >= nc ||
+                    ((!(capx[c] == sectx[c][i] &&
+                        capy[c] == secty[c][i])) &&
+                     (!(new_x(capx[c] + 2) == sectx[c][i] &&
+                        capy[c] == secty[c][i]))))) {
+                   ELEV = INFINITY;
+                   break;
+               }
+           --k;
        }
-      --k;
-    }
 
 /* Elevate land that is not mountain and not capital */
 
-    for (i = 0; i < ns; ++i)
-      dmoun[i] = distance_to_mountain();
-    dk=(ns-nm-((c<nc)?3:1)>0)?(100*(HIGHMIN-LANDMIN))/(ns-nm-((c<nc)?3:1)):100*INFINITY;
-    for (k = 100*(HIGHMIN - 1);; k -= dk) {
-      highest = -INFINITY;
-      where = -1;
-      for (i = 0; i < ns; ++i) {
-       if (ELEV != INFINITY && (c >= nc ||
-            ((!(capx[c] == sectx[c][i] && capy[c] == secty[c][i])) &&
-             (!(new_x(capx[c] + 2) == sectx[c][i] && capy[c] == secty[c][i])))))
-         {
-           h = 3*(5 - dmoun[i]) + dsea[i];
-           if (h > highest) {
-             highest = h;
-             where = i;
+       for (i = 0; i < ns; ++i)
+           dmoun[i] = distance_to_mountain();
+       dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
+         (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
+         100 * INFINITY;
+       for (k = 100 * (HIGHMIN - 1);; k -= dk) {
+           highest = -INFINITY;
+           where = -1;
+           for (i = 0; i < ns; ++i) {
+               if (ELEV != INFINITY &&
+                   (c >= nc || ((!(capx[c] == sectx[c][i] &&
+                                   capy[c] == secty[c][i])) &&
+                                (!(new_x(capx[c] + 2) == sectx[c][i] &&
+                                   capy[c] == secty[c][i]))))) {
+                   h = 3 * (5 - dmoun[i]) + dsea[i];
+                   if (h > highest) {
+                       highest = h;
+                       where = i;
+                   }
+               }
            }
-         }
-      }
-      if (where == -1)
-       break;
-      newk = k/100;
-      if (newk >= HILLMIN && newk < PLATMIN)
-       newk = PLATMIN;
-      if (newk < LANDMIN)
-       newk = LANDMIN;
-      elev[sectx[c][where]][secty[c][where]] = newk;   
-      dsea[where] = -INFINITY;
-      dmoun[where] = INFINITY;
-    }
+           if (where == -1)
+               break;
+           newk = k / 100;
+           if (newk >= HILLMIN && newk < PLATMIN)
+               newk = PLATMIN;
+           if (newk < LANDMIN)
+               newk = LANDMIN;
+           elev[sectx[c][where]][secty[c][where]] = newk;
+           dsea[where] = -INFINITY;
+           dmoun[where] = INFINITY;
+       }
 
 /* Elevate the mountains and capitals */
 
-    for (i = 0; i < ns; ++i) {
-      if (ELEV == INFINITY) {
-       if (dsea[i] == 1)
-         ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
-       else
-         ELEV = HIGHMIN + rnd((256-HIGHMIN)/2) + rnd((256-HIGHMIN)/2);
-      }
-      else if ((c < nc &&
-            ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
-            ((new_x(capx[c] + 2) == sectx[c][i] && capy[c] == secty[c][i])))
-       ELEV = PLATMIN;
+       for (i = 0; i < ns; ++i) {
+           if (ELEV == INFINITY) {
+               if (dsea[i] == 1)
+                   ELEV = HILLMIN + roll0(PLATMIN - HILLMIN);
+               else
+                   ELEV = HIGHMIN + roll0((256 - HIGHMIN) / 2) +
+                     roll0((256 - HIGHMIN) / 2);
+           } else if (c < nc &&
+                      (((capx[c] == sectx[c][i] && capy[c] == secty[c][i])) ||
+                       ((new_x(capx[c] + 2) == sectx[c][i] &&
+                         capy[c] == secty[c][i]))))
+               ELEV = PLATMIN;
+       }
     }
-  }
 }
 
 #define distance_to_land() distance_to_what(x, y, 1)
 
-void
+static void
 elevate_sea(void)
 {
-  int x, y;
+    int x, y;
 
-  for (y = 0; y < WORLD_Y; ++y) {
-    for (x = y%2; x < WORLD_X; x +=2) {
-      if (elev[x][y] == -INFINITY)
-       elev[x][y] = - rnd((distance_to_land()*20 + 27)) - 1;
+    for (y = 0; y < WORLD_Y; ++y) {
+       for (x = y % 2; x < WORLD_X; x += 2) {
+           if (elev[x][y] == -INFINITY)
+               elev[x][y] = -roll(distance_to_land() * 20 + 27);
        }
-  }
+    }
 }
 
 /****************************************************************************
   ADD THE RESOURCES
 ****************************************************************************/
 
-int
-set_fert(e)
-int e;
+static int
+set_fert(int e)
 {
-  int fert = 0;
-  if (e < LANDMIN)
-    fert = LANDMIN - e + 40;
-  else if (e < FERT_MAX)
-    fert = (140*(FERT_MAX - e))/(FERT_MAX - LANDMIN);
-  if (fert > 120)
-    fert = 120;
-  return fert;
+    int fert = 0;
+    if (e < LANDMIN)
+       fert = LANDMIN - e + 40;
+    else if (e < FERT_MAX)
+       fert = (120 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
+    if (fert > 100)
+       fert = 100;
+    return fert;
 }
 
-int
-set_oil(e)
-int e;
+static int
+set_oil(int e)
 {
-  int oil = 0;
-  if (e < LANDMIN)
-    oil = (LANDMIN - e)*2 + rnd(2);
-  else if (e <= OIL_MAX)
-    oil = (120*(OIL_MAX - e + 1))/(OIL_MAX - LANDMIN + 1);
-  if (oil > 100)
-    oil = 100;
-  return oil;
+    int oil = 0;
+    if (e < LANDMIN)
+       oil = (LANDMIN - e) * 2 + roll0(2);
+    else if (e <= OIL_MAX)
+       oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
+    if (oil > 100)
+       oil = 100;
+    return oil;
 }
 
-int
-set_iron(e)
-int e;
+static int
+set_iron(int e)
 {
-  int iron = 0;
-  if (e >= IRON_MIN && e < HIGHMIN)
-    iron = (120*(e - IRON_MIN + 1))/(HIGHMIN - IRON_MIN);
-  if (iron > 100)
-    iron = 100;
-  return iron;
+    int iron = 0;
+    if (e >= IRON_MIN && e < HIGHMIN)
+       iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
+    if (iron > 100)
+       iron = 100;
+    return iron;
 }
 
-int
-set_gold(e)
-int e;
+static int
+set_gold(int e)
 {
-  int gold = 0;
-  if (e >= GOLD_MIN) {
-    if (e < HIGHMIN)
-      gold = (80*(e - GOLD_MIN + 1))/(HIGHMIN - GOLD_MIN);
-    else
-      gold = 100 - 20 * HIGHMIN / e;
-  }
-  if (gold > 100)
-    gold = 100;
-  return gold;
+    int gold = 0;
+    if (e >= GOLD_MIN) {
+       if (e < HIGHMIN)
+           gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
+       else
+           gold = 100 - 20 * HIGHMIN / e;
+    }
+    if (gold > 100)
+       gold = 100;
+    return gold;
 }
 
-int
-set_uran(e)
-int e;
+static int
+set_uran(int e)
 {
-  int uran = 0;
-  if (e >= URAN_MIN && e < HIGHMIN)
-    uran = (120*(e - URAN_MIN + 1))/(HIGHMIN - URAN_MIN);
-  if (uran > 100)
-    uran = 100;
-  return uran;
+    int uran = 0;
+    if (e >= URAN_MIN && e < HIGHMIN)
+       uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
+    if (uran > 100)
+       uran = 100;
+    return uran;
 }
 
-void
-add_resources(sct)
-struct sctstr *sct;
+static void
+add_resources(struct sctstr *sct)
 {
-  sct->sct_fertil = set_fert(sct->sct_elev);
-  sct->sct_oil    = set_oil(sct->sct_elev);
-  sct->sct_min    = set_iron(sct->sct_elev);
-  sct->sct_gmin   = set_gold(sct->sct_elev);
-  sct->sct_uran   = set_uran(sct->sct_elev);
+    sct->sct_fertil = set_fert(sct->sct_elev);
+    sct->sct_oil = set_oil(sct->sct_elev);
+    sct->sct_min = set_iron(sct->sct_elev);
+    sct->sct_gmin = set_gold(sct->sct_elev);
+    sct->sct_uran = set_uran(sct->sct_elev);
 }
 
 /****************************************************************************
   DESIGNATE THE SECTORS
 ****************************************************************************/
 
-void
+static void
 write_sects(void)
 {
-  register struct sctstr *sct;
-  int c, x, y, total;
-  
-  /*  sct = &sects[0][0];*/
-  sct = sectsbuf;
-  for (y = 0; y < YSIZE; y++) {
-    for (x = 0; x < XSIZE; x++, sct++) {
-      fl_sct_init(x*2 + (y & 01), y, (s_char *) sct);
-      total = elev[sct->sct_x][y];
-      if (total < LANDMIN) {
-       sct->sct_type = SCT_WATER;
-      } else if (total < HILLMIN)
-       sct->sct_type = SCT_RURAL;
-      else if (total < PLATMIN)
-       sct->sct_type = SCT_MOUNT;
-      else if (total < HIGHMIN)
-       sct->sct_type = SCT_RURAL;
-      else
-       sct->sct_type = SCT_MOUNT;
-      sct->sct_elev = total;
-      sct->sct_newtype = sct->sct_type;
-      if (ORE)
-       add_resources(sct);
-    }
-  }
-  if (AIRPORT_MARKER)
-    for (c = 0; c < nc; ++c) {
-      sects[capy[c]][capx[c]/2 + capy[c]%2].sct_type = SCT_AIRPT;
-      sects[capy[c]][capx[c]/2 + capy[c]%2].sct_newtype = SCT_AIRPT;
+    struct sctstr *sct;
+    int c, x, y, total;
+
+    for (y = 0; y < WORLD_Y; y++) {
+       for (x = y % 2; x < WORLD_X; x += 2) {
+           sct = getsectp(x, y);
+           total = elev[x][y];
+           if (total < LANDMIN) {
+               sct->sct_type = SCT_WATER;
+           } else if (total < HILLMIN)
+               sct->sct_type = SCT_RURAL;
+           else if (total < PLATMIN)
+               sct->sct_type = SCT_MOUNT;
+           else if (total < HIGHMIN)
+               sct->sct_type = SCT_RURAL;
+           else
+               sct->sct_type = SCT_MOUNT;
+           sct->sct_elev = total;
+           sct->sct_newtype = sct->sct_type;
+           if (ORE)
+               add_resources(sct);
+       }
     }
-}
-
-/****************************************************************************
-  WRITE ALL THIS STUFF TO THE FILE
-****************************************************************************/
-int
-write_file(void)
-{
-  int n;
-
-  /*  if ((n = write(the_file, sects, sizeof(sects))) < 0) {*/
-  if ((n = write(the_file, sectsbuf, YSIZE * XSIZE * sizeof(struct sctstr))) < 0) {
-    perror(empfile[EF_SECTOR].file);
-    return -1;
-  }
-  if (n != (int)(YSIZE * XSIZE * sizeof(struct sctstr))) {
-    printf("%s:partial write\n", empfile[EF_SECTOR].file);
-    return -1;
-  }
-  close(the_file);
-  return 0;
+    if (AIRPORT_MARKER)
+       for (c = 0; c < nc; ++c) {
+           sct = getsectp(capx[c], capy[c]);
+           sct->sct_type = SCT_AIRPT;
+           sct->sct_newtype = SCT_AIRPT;
+       }
+    set_coastal_flags();
 }
 
 /****************************************************************************
   PRINT A PICTURE OF THE MAP TO YOUR SCREEN
 ****************************************************************************/
-void
+static void
 output(void)
 {
-  int i, j;
-  if (opt_BLITZ)
-    translate_continents();
-  if (quiet == 0) {
-    for (i = 0; i < WORLD_Y; ++i) {
-      puts("");
-      if (i%2)
-         printf(" ");
-      for (j = i%2; j < WORLD_X; j += 2) {
-       if (own[j][i] == -1)
-           printf(". ");
-       else {
-         printf("%c ", map_symbol(j,i));
-       }
-      }
-    }
-  }
-  if (AIRPORT_MARKER) 
-      printf("\n\nEach continent is marked by a \"*\" on the map (to distinguish them from\nthe islands).  You can redesignate these airfields to wilderness sectors\none at a time, each time you add a new country to the game.\n");
-}
-
-/* Reorder the continents from top left to bottom right */
-void
-translate_continents(void)
-{
-  int i, j, n = 0, k, gotit, c;
-  int *trans, *trans_cont, *oldcapx, *oldcapy;
-
-  trans = (int *)calloc(nc, sizeof(int));
-  trans_cont = (int *)calloc(nc, sizeof(int));
-  oldcapx = (int *)calloc(nc, sizeof(int));
-  oldcapy = (int *)calloc(nc, sizeof(int));
-
-  for (i = 0; i < WORLD_Y; ++i) {
-    for (j = i%2; j < WORLD_X; j += 2) {
-      if (own[j][i] >-1 && own[j][i] < nc) {
-       gotit = 0;
-       for (k = 0; k < n; ++k) {
-         if (trans[k] == own[j][i])
-           gotit = 1;
-       }
-       if (!gotit) {
-         if (n > nc) {
-           printf("fairland: BUG in translate continents!  mail stevens@math.utoronto.ca\n");
-           exit (2);
-         }
-         trans[n] = own[j][i];
-         trans_cont[own[j][i]] = n;
-         ++n;
+    int i, j;
+    if (quiet == 0) {
+       for (i = 0; i < WORLD_Y; ++i) {
+           puts("");
+           if (i % 2)
+               printf(" ");
+           for (j = i % 2; j < WORLD_X; j += 2) {
+               if (own[j][i] == -1)
+                   printf(". ");
+               else {
+                   printf("%c ", map_symbol(j, i));
+               }
+           }
        }
-      }
     }
-  }
-  for (i = 0; i < WORLD_Y; ++i) {
-    for (j = i%2; j < WORLD_X; j += 2) {
-      if (own[j][i] >-1 && own[j][i] < nc) {
-       own[j][i] = trans_cont[own[j][i]];
-      }
-    }
-  }
-  for (c = 0; c < nc; ++c) {
-    oldcapx[c] = capx[c];
-    oldcapy[c] = capy[c];
-  }
-  for (c = 0; c < nc; ++c) {
-    capx[c] = oldcapx[trans[c]];
-    capy[c] = oldcapy[trans[c]];
-  }
+    if (AIRPORT_MARKER)
+       printf("\n\nEach continent is marked by a \"*\" on the map (to distinguish them from\n"
+              "the islands).  You can redesignate these airfields to wilderness sectors\n"
+              "one at a time, each time you add a new country to the game.\n");
 }
 
-int
+static int
 map_symbol(int x, int y)
 {
-  int c, iscap = 0;
-
-  for (c = 0; c < nc; ++c)
-    if ((x == capx[c] && y == capy[c]) || (x == new_x(capx[c]+2) && y == capy[c]))
-      iscap = 1;
-  if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN) || elev[x][y] >= HIGHMIN)
-    return '^';
-  return own[x][y]>=nc?'%':iscap?'#':numletter[own[x][y] % 62];
+    int c, iscap = 0;
+
+    for (c = 0; c < nc; ++c)
+       if ((x == capx[c] && y == capy[c])
+           || (x == new_x(capx[c] + 2) && y == capy[c]))
+           iscap = 1;
+    if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
+       || elev[x][y] >= HIGHMIN)
+       return '^';
+    return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
 }
 
 /***************************************************************************
   WRITE A SCRIPT FOR PLACING CAPITALS
 ****************************************************************************/
-int
+static int
 write_newcap_script(void)
 {
-  int c;
-  FILE *script = fopen(outfile, "w");
+    int c;
+    FILE *script = fopen(outfile, "w");
 
-  if (!script) {
-    printf("fairland: error, unable to write to %s.\n", outfile);
-    return -1;
-  }
+    if (!script) {
+       printf("fairland: error, unable to write to %s.\n", outfile);
+       return -1;
+    }
 
-  for (c = 0; c < nc; ++c) {
-    fprintf(script, "add %d %d %d n i\n", c+1, c+1, c+1);
-    if (AIRPORT_MARKER)
-      fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
-    fprintf(script, "newcap %d %d,%d\n", c+1, capx[c], capy[c]);
-  }
-  fprintf(script, "add %d visitor visitor v i\n", c+1);
-  ++c;
-  fclose (script);
-  if (quiet == 0)
-      printf("\n\nA script for adding all the countries can be found in \"%s\".\n",
-            outfile);
-  if (ORE && quiet == 0)
-    printf("\t***IMPORTANT: Resources have already been added***\n\tYou do NOT need to run the ore program.\n");
-  return 0;
+    for (c = 0; c < nc; ++c) {
+       fprintf(script, "add %d %d %d p\n", c + 1, c + 1, c + 1);
+       if (AIRPORT_MARKER)
+           fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
+       fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
+    }
+    fprintf(script, "add %d visitor visitor v\n", c + 1);
+    fclose(script);
+    return 0;
 }
 
-static void qprint (str)
-const char *str;
+static void
+qprint(const char *const fmt, ...)
 {
-  if (quiet == 0)
-      fputs (str, stdout);
+    va_list ap;
+
+    if (!quiet) {
+       va_start(ap, fmt);
+       vfprintf(stdout, fmt, ap);
+       va_end(ap);
+    }
 }
 
-void
-fl_sct_init(coord x, coord y, s_char *ptr)
+static void
+set_coastal_flags(void)
 {
-       struct  sctstr *sp = (struct sctstr *) ptr;
-
-       sp->ef_type = EF_SECTOR;
-       sp->sct_x = x;
-       sp->sct_y = y;
-       sp->sct_dist_x = x;
-       sp->sct_dist_y = y;
-       sp->sct_road = 0;
-       sp->sct_rail = 0;
-       sp->sct_defense = 0;
+    int i, j;
+    struct sctstr *sp;
+
+    qprint("setting coastal flags...\n");
+    for (i = 0; i < nc; ++i) {
+       for (j = 0; j < sc; j++) {
+           sp = getsectp(sectx[i][j], secty[i][j]);
+           sp->sct_coastal = sectc[i][j];
+       }
+    }
+    for (i = nc; i < nc + ni; ++i) {
+       for (j = 0; j < isecs[i]; j++) {
+           sp = getsectp(sectx[i][j], secty[i][j]);
+           sp->sct_coastal = sectc[i][j];
+       }
+    }
 }