]> git.pond.sub.org Git - empserver/blob - src/util/fairland.c
9f28769c1891fd0cb063fee72d56384bdb3f5f10
[empserver] / src / util / fairland.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2020, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                Ken Stevens, Steve McClure, Markus Armbruster
5  *
6  *  Empire is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  *  ---
20  *
21  *  See files README, COPYING and CREDITS in the root of the source
22  *  tree for related information and legal notices.  It is expected
23  *  that future projects/authors will amend these files as needed.
24  *
25  *  ---
26  *
27  *  fairland.c: Create a nice, new world
28  *
29  *  Known contributors to this file:
30  *     Ken Stevens, 1995
31  *     Steve McClure, 1998
32  *     Markus Armbruster, 2004-2020
33  */
34
35 /*
36  * How fairland works
37  *
38  * 1. Place capitals
39  *
40  * Place the capitals on the torus in such a way so as to maximize
41  * their distances from one another.  This uses the perturbation
42  * technique of calculus of variations.
43  *
44  * 2. Grow start islands ("continents")
45  *
46  * For all continents, add the first sector at the capital's location,
47  * and the second right to it.  These are the capital sectors.  Then
48  * add one sector to each continent in turn, until they have the
49  * specified size.
50  *
51  * Growth uses weighted random sampling to pick one sector from the
52  * set of adjacent sea sectors that aren't too close to another
53  * continent.  Growth operates in spiking mode with a chance given by
54  * the spike percentage.  When "spiking", a sector's weight increases
55  * with number of adjacent sea sectors.  This directs the growth away
56  * from land, resulting in spikes.  When not spiking, the weight
57  * increases with the number of adjacent land sectors.  This makes the
58  * island more rounded.
59  *
60  * If growing fails due to lack of room, start over.  If it fails too
61  * many times, give up and terminate unsuccessfully.
62  *
63  * 3. Place and grow additional islands
64  *
65  * Each continent has a "sphere of influence": the set of sectors
66  * closer to it than to any other continent.  Each island is entirely
67  * in one such sphere, and each sphere contains the same number of
68  * islands.
69  *
70  * Place and grow islands in spheres in turn.  Place the first sector
71  * randomly, pick an island size, then grow the island to that size.
72  *
73  * If placement fails due to lack of room, start over, just like for
74  * continents.
75  *
76  * Growing works as for continents, except the minimum distance for
77  * additional islands applies, and growing simply stops when there is
78  * no room.
79  *
80  * 4. Compute elevation
81  *
82  * Elevate islands one after the other.
83  *
84  * First, place the specified number of mountains randomly.
85  * Probability increases with distance to sea.
86  *
87  * Last, elevate mountains and the capitals.  Pick coastal mountain
88  * elevation randomly from an interval of medium elevations reserved
89  * for them.  Pick non-coastal mountain elevation randomly from an
90  * interval of high elevation reserved for them.  Set capital
91  * elevation to a fixed, medium value.
92  *
93  * In between, elevate the remaining land one by one, working from
94  * mountains towards the sea, and from the elevation just below the
95  * non-coastal mountains' interval linearly down to 1, avoiding the
96  * coastal mountains' interval.
97  *
98  * This gives islands of the same size the same set of elevations,
99  * except for mountains.
100  *
101  * Elevate sea: pick a random depth from an interval that deepens with
102  * the distance to land.
103  *
104  * 5. Set resources
105  *
106  * Sector resources are simple functions of elevation.  You can alter
107  * macros OIL_MAX, IRON_MIN, GOLD_MIN, FERT_MAX, and URAN_MIN to
108  * customize them.
109  */
110
111 #include <config.h>
112
113 #include <assert.h>
114 #include <errno.h>
115 #include <limits.h>
116 #include <stdarg.h>
117 #include <stdio.h>
118 #include <unistd.h>
119 #include "chance.h"
120 #include "optlist.h"
121 #include "path.h"
122 #include "prototypes.h"
123 #include "sect.h"
124 #include "version.h"
125 #include "xy.h"
126
127 /* The following five numbers refer to elevation under which (in the case of
128    fertility or oil) or over which (in the case of iron, gold, and uranium)
129    sectors with that elevation will contain that resource.  Elevation ranges
130    from 0 to 100 */
131
132 /* raise FERT_MAX for more fertility */
133 #define FERT_MAX   56
134
135 /* raise OIL_MAX for more oil */
136 #define OIL_MAX    33
137
138 /* lower IRON_MIN for more iron */
139 #define IRON_MIN   22
140
141 /* lower GOLD_MIN for more gold */
142 #define GOLD_MIN   36
143
144 /* lower URAN_MIN for more uranium */
145 #define URAN_MIN   56
146
147 /* do not change these 4 defines */
148 #define LANDMIN         1       /* plate altitude for normal land */
149 #define HILLMIN         34      /* plate altitude for hills */
150 #define PLATMIN         36      /* plate altitude for plateau */
151 #define HIGHMIN         98      /* plate altitude for mountains */
152
153 static void qprint(const char * const fmt, ...)
154     ATTRIBUTE((format (printf, 1, 2)));
155
156 /*
157  * Program arguments and options
158  */
159 static char *program_name;
160 static int nc, sc;              /* number and size of continents */
161 static int ni, is;              /* number and size of islands */
162 #define DEFAULT_SPIKE 10
163 static int sp = DEFAULT_SPIKE;  /* spike percentage */
164 #define DEFAULT_MOUNTAIN 0
165 static int pm = DEFAULT_MOUNTAIN; /* mountain percentage */
166 #define DEFAULT_CONTDIST 2
167 static int di = DEFAULT_CONTDIST; /* min. distance between continents */
168 #define DEFAULT_ISLDIST 1
169 static int id = DEFAULT_ISLDIST;  /* ... continents and islands */
170 /* don't let the islands crash into each other.
171    1 = don't merge, 0 = merge. */
172 static int DISTINCT_ISLANDS = 1;
173 static int quiet;
174 #define DEFAULT_OUTFILE_NAME "newcap_script"
175 static const char *outfile = DEFAULT_OUTFILE_NAME;
176
177 #define STABLE_CYCLE 4          /* stability required for perterbed capitals */
178 #define INFINITE_ELEVATION 999
179
180 /* these defines prevent infinite loops:
181 */
182 #define DRIFT_BEFORE_CHECK ((WORLD_X + WORLD_Y)/2)
183 #define DRIFT_MAX ((WORLD_X + WORLD_Y)*2)
184 #define MOUNTAIN_SEARCH_MAX 1000        /* how long do we try to place mountains */
185
186 /* handy macros:
187 */
188
189 #define new_x(newx) (((newx) + WORLD_X) % WORLD_X)
190 #define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y)
191
192 /*
193  * Island sizes
194  * isecs[i] is the size of the i-th island.
195  */
196 static int *isecs;
197
198 static int *capx, *capy;        /* location of the nc capitals */
199
200 static int **own;               /* owner of the sector.  -1 means water */
201
202 /*
203  * Adjacent land sectors
204  * adj_land[XYOFFSET(x, y)] bit d is set exactly when the sector next
205  * to x, y in direction d is land.
206  */
207 static unsigned char *adj_land;
208
209 /*
210  * Exclusive zones
211  * Each island is surrounded by an exclusive zone where only it may
212  * grow.  The width of the zone depends on minimum distances.
213  * While growing continents, it is @di sectors wide.
214  * While growing additional islands, it is @id sectors wide.
215  * DISTINCT_ISLANDS nullifies the exclusive zone then.
216  * xzone[XYOFFSET(x, y)] is -1 when the sector is in no exclusive
217  * zone, a (non-negative) island number when it is in that island's
218  * exclusive zone and no other, and -2 when it is in multiple
219  * exclusive zones.
220  */
221 static short *xzone;
222
223 /*
224  * Set of sectors seen already
225  * Increment @cur_seen to empty the set of sectors seen, set
226  * seen[XYOFFSET(x, y)] to @cur_seen to add x,y to the set.
227  */
228 static unsigned *seen;
229 static unsigned cur_seen;
230
231 /*
232  * Closest continent and "distance"
233  * closest[XYOFFSET(x, y)] is the closest continent's number.
234  * distance[] is complicated; see init_spheres_of_influence().
235  */
236 static natid *closest;
237 static unsigned short *distance;
238
239 /*
240  * Queue for breadth-first search
241  */
242 static int *bfs_queue;
243 static int bfs_queue_head, bfs_queue_tail;
244
245 static int **elev;              /* elevation of the sectors */
246 static int **sectx, **secty;    /* the sectors for each continent */
247 static int **sectc;             /* which sectors are on the coast? */
248 static int *weight;             /* used for placing mountains */
249 static int *dsea, *dmoun;       /* the dist to the ocean and mountain */
250
251 #define NUMTRIES 10             /* keep trying to grow this many times */
252
253 static const char *numletter =
254     "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
255
256 static void help(char *);
257 static void usage(void);
258 static void parse_args(int argc, char *argv[]);
259 static void allocate_memory(void);
260 static void init(void);
261 static int drift(void);
262 static int grow_continents(void);
263 static void create_elevations(void);
264 static void write_sects(void);
265 static void output(void);
266 static int write_newcap_script(void);
267 static int stable(int);
268 static void elevate_land(void);
269 static void elevate_sea(void);
270 static void set_coastal_flags(void);
271
272 static void print_vars(void);
273 static void fl_move(int);
274 static int grow_islands(void);
275
276 /* Debugging aids: */
277 void print_own_map(void);
278 void print_xzone_map(void);
279 void print_closest_map(void);
280 void print_distance_map(void);
281 void print_elev_map(void);
282
283 /****************************************************************************
284   MAIN
285 ****************************************************************************/
286
287 int
288 main(int argc, char *argv[])
289 {
290     int opt;
291     char *config_file = NULL;
292     int try, done;
293     unsigned rnd_seed = 0;
294     int seed_set = 0;
295
296     program_name = argv[0];
297
298     while ((opt = getopt(argc, argv, "e:hiqR:s:v")) != EOF) {
299         switch (opt) {
300         case 'e':
301             config_file = optarg;
302             break;
303         case 'i':
304             DISTINCT_ISLANDS = 0;
305             break;
306         case 'q':
307             quiet = 1;
308             break;
309         case 'R':
310             rnd_seed = strtoul(optarg, NULL, 10);
311             seed_set = 1;
312             break;
313         case 's':
314             outfile = optarg;
315             break;
316         case 'h':
317             usage();
318             exit(0);
319         case 'v':
320             printf("%s\n\n%s", version, legal);
321             exit(0);
322         default:
323             help(NULL);
324             exit(1);
325         }
326     }
327
328     if (!seed_set)
329         rnd_seed = pick_seed();
330     seed_prng(rnd_seed);
331     empfile_init();
332     if (emp_config(config_file) < 0)
333         exit(1);
334     empfile_fixup();
335
336     parse_args(argc - optind, argv + optind);
337
338     allocate_memory();
339     print_vars();
340
341     qprint("\n        #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
342     qprint("seed is %u\n", rnd_seed);
343     try = 0;
344     do {
345         init();
346         if (try)
347             qprint("\ntry #%d (out of %d)...\n", try + 1, NUMTRIES);
348         qprint("placing capitals...\n");
349         if (!drift())
350             qprint("unstable drift\n");
351         qprint("growing continents...\n");
352         done = grow_continents();
353         if (!done)
354             continue;
355         qprint("growing islands:");
356         done = grow_islands();
357     } while (!done && ++try < NUMTRIES);
358     if (!done) {
359         fprintf(stderr, "%s: world not large enough for this much land\n",
360                 program_name);
361         exit(1);
362     }
363     qprint("elevating land...\n");
364     create_elevations();
365
366     qprint("writing to sectors file...\n");
367     if (!write_newcap_script())
368         exit(1);
369     if (chdir(gamedir)) {
370         fprintf(stderr, "%s: can't chdir to %s (%s)\n",
371                 program_name, gamedir, strerror(errno));
372         exit(1);
373     }
374     if (!ef_open(EF_SECTOR, EFF_MEM | EFF_NOTIME))
375         exit(1);
376     write_sects();
377     if (!ef_close(EF_SECTOR))
378         exit(1);
379
380     output();
381     qprint("\n\nA script for adding all the countries can be found in \"%s\".\n",
382            outfile);
383     exit(0);
384 }
385
386 static void
387 print_vars(void)
388 {
389     if (quiet)
390         return;
391     puts("Creating a planet with:\n");
392     printf("%d continents\n", nc);
393     printf("continent size: %d\n", sc);
394     printf("number of islands: %d\n", ni);
395     printf("average size of islands: %d\n", is);
396     printf("spike: %d%%\n", sp);
397     printf("%d%% of land is mountain (each continent will have %d mountains)\n",
398            pm, (pm * sc) / 100);
399     printf("minimum distance between continents: %d\n", di);
400     printf("minimum distance from islands to continents: %d\n", id);
401     printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
402 }
403
404 static void
405 help(char *complaint)
406 {
407     if (complaint)
408         fprintf(stderr, "%s: %s\n", program_name, complaint);
409     fprintf(stderr, "Try -h for help.\n");
410 }
411
412 static void
413 usage(void)
414 {
415     printf("Usage: %s [OPTION]... NC SC [NI] [IS] [SP] [PM] [DI] [ID]\n"
416            "  -e CONFIG-FILE  configuration file\n"
417            "                  (default %s)\n"
418            "  -i              islands may merge\n"
419            "  -q              quiet\n"
420            "  -R SEED         seed for random number generator\n"
421            "  -s SCRIPT       name of script to create (default %s)\n"
422            "  -h              display this help and exit\n"
423            "  -v              display version information and exit\n"
424            "  NC              number of continents\n"
425            "  SC              continent size\n"
426            "  NI              number of islands (default NC)\n"
427            "  IS              average island size (default SC/2)\n"
428            "  SP              spike percentage: 0 = round, 100 = snake (default %d)\n"
429            "  PM              percentage of land that is mountain (default %d)\n"
430            "  DI              minimum distance between continents (default %d)\n"
431            "  ID              minimum distance from islands to continents (default %d)\n",
432            program_name, dflt_econfig, DEFAULT_OUTFILE_NAME,
433            DEFAULT_SPIKE, DEFAULT_MOUNTAIN, DEFAULT_CONTDIST, DEFAULT_ISLDIST);
434 }
435
436 static void
437 parse_args(int argc, char *argv[])
438 {
439     int dist_max = mapdist(0, 0, WORLD_X / 2, WORLD_Y / 2);
440
441     if (argc < 2) {
442         help("missing arguments");
443         exit(1);
444     }
445     if (argc > 8) {
446         help("too many arguments");
447         exit(1);
448     }
449     nc = atoi(argv[0]);
450     if (nc < 1) {
451         fprintf(stderr, "%s: number of continents must be > 0\n",
452                 program_name);
453         exit(1);
454     }
455
456     sc = atoi(argv[1]);
457     if (sc < 2) {
458         fprintf(stderr, "%s: size of continents must be > 1\n",
459                 program_name);
460         exit(1);
461     }
462
463     ni = nc;
464     is = sc / 2;
465
466     if (argc > 2)
467         ni = atoi(argv[2]);
468     if (ni < 0) {
469         fprintf(stderr, "%s: number of islands must be >= 0\n",
470                 program_name);
471         exit(1);
472     }
473     if (ni % nc) {
474         fprintf(stderr, "%s: number of islands must be a multiple of"
475                 " the number of continents\n",
476                 program_name);
477         exit(1);
478     }
479
480     if (argc > 3)
481         is = atoi(argv[3]);
482     if (is < 1) {
483         fprintf(stderr, "%s: size of islands must be > 0\n",
484                 program_name);
485         exit(1);
486     }
487
488     if (argc > 4)
489         sp = atoi(argv[4]);
490     if (sp < 0 || sp > 100) {
491         fprintf(stderr,
492                 "%s: spike percentage must be between 0 and 100\n",
493                 program_name);
494         exit(1);
495     }
496
497     if (argc > 5)
498         pm = atoi(argv[5]);
499     if (pm < 0 || pm > 100) {
500         fprintf(stderr,
501                 "%s: mountain percentage must be between 0 and 100\n",
502                 program_name);
503         exit(1);
504     }
505
506     if (argc > 6)
507         di = atoi(argv[6]);
508     if (di < 0) {
509         fprintf(stderr, "%s: distance between continents must be >= 0\n",
510                 program_name);
511         exit(1);
512     }
513     if (di > dist_max) {
514         fprintf(stderr, "%s: distance between continents too large\n",
515                 program_name);
516         exit(1);
517     }
518
519     if (argc > 7)
520         id = atoi(argv[7]);
521     if (id < 0) {
522         fprintf(stderr,
523                 "%s: distance from islands to continents must be >= 0\n",
524                 program_name);
525         exit(1);
526     }
527     if (id > dist_max) {
528         fprintf(stderr,
529                 "%s: distance from islands to continents too large\n",
530                 program_name);
531         exit(1);
532     }
533 }
534
535 /****************************************************************************
536   VARIABLE INITIALIZATION
537 ****************************************************************************/
538
539 static void
540 allocate_memory(void)
541 {
542     int i;
543
544     capx = calloc(nc, sizeof(int));
545     capy = calloc(nc, sizeof(int));
546     own = calloc(WORLD_X, sizeof(int *));
547     adj_land = malloc(WORLD_SZ() * sizeof(*adj_land));
548     xzone = malloc(WORLD_SZ() * sizeof(*xzone));
549     seen = calloc(WORLD_SZ(), sizeof(*seen));
550     closest = malloc(WORLD_SZ() * sizeof(*closest));
551     distance = malloc(WORLD_SZ() * sizeof(*distance));
552     bfs_queue = malloc(WORLD_SZ() * sizeof(*bfs_queue));
553     elev = calloc(WORLD_X, sizeof(int *));
554     for (i = 0; i < WORLD_X; ++i) {
555         own[i] = calloc(WORLD_Y, sizeof(int));
556         elev[i] = calloc(WORLD_Y, sizeof(int));
557     }
558     sectx = calloc(nc + ni, sizeof(int *));
559     secty = calloc(nc + ni, sizeof(int *));
560     sectc = calloc(nc + ni, sizeof(int *));
561     isecs = calloc(nc + ni, sizeof(int));
562     weight = calloc(MAX(sc, is * 2), sizeof(int));
563     dsea = calloc(MAX(sc, is * 2), sizeof(int));
564     dmoun = calloc(MAX(sc, is * 2), sizeof(int));
565     for (i = 0; i < nc; ++i) {
566         sectx[i] = calloc(sc, sizeof(int));
567         secty[i] = calloc(sc, sizeof(int));
568         sectc[i] = calloc(sc, sizeof(int));
569     }
570     for (i = nc; i < nc + ni; ++i) {
571         sectx[i] = calloc(is * 2, sizeof(int));
572         secty[i] = calloc(is * 2, sizeof(int));
573         sectc[i] = calloc(is * 2, sizeof(int));
574     }
575
576 }
577
578 static void
579 init(void)
580 {
581     int i, j;
582
583     for (i = 0; i < WORLD_X; ++i) {
584         for (j = 0; j < WORLD_Y; ++j) {
585             own[i][j] = -1;
586         }
587     }
588     memset(adj_land, 0, WORLD_SZ() * sizeof(*adj_land));
589 }
590
591 /****************************************************************************
592   DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
593 ****************************************************************************/
594
595 /*
596  * How isolated is capital @j at @newx,@newy?
597  * Return the distance to the closest other capital.
598  */
599 static int
600 iso(int j, int newx, int newy)
601 {
602     int d = INT_MAX;
603     int i, md;
604
605     for (i = 0; i < nc; ++i) {
606         if (i == j)
607             continue;
608         md = mapdist(capx[i], capy[i], newx, newy);
609         if (md < d)
610             d = md;
611     }
612
613     return d;
614 }
615
616 /*
617  * Drift the capitals
618  * Return 1 for a stable drift, 0 for an unstable one.
619  */
620 static int
621 drift(void)
622 {
623     int turns, i;
624
625     for (i = 0; i < nc; i++) {
626         capy[i] = (2 * i) / WORLD_X;
627         capx[i] = (2 * i) % WORLD_X + capy[i] % 2;
628         if (capy[i] >= WORLD_Y) {
629             fprintf(stderr,
630                     "%s: world not big enough for all the continents\n",
631                     program_name);
632             exit(1);
633         }
634     }
635
636     for (turns = 0; turns < DRIFT_MAX; ++turns) {
637         if (stable(turns))
638             return 1;
639         for (i = 0; i < nc; ++i)
640             fl_move(i);
641     }
642     return 0;
643 }
644
645 /*
646  * Has the drift stabilized?
647  * @turns is the number of turns so far.
648  */
649 static int
650 stable(int turns)
651 {
652     static int mc[STABLE_CYCLE];
653     int i, isod, d = 0, stab = 1;
654
655     if (!turns) {
656         for (i = 0; i < STABLE_CYCLE; i++)
657             mc[i] = i;
658     }
659
660     if (turns <= DRIFT_BEFORE_CHECK)
661         return 0;
662
663     for (i = 0; i < nc; ++i) {
664         isod = iso(i, capx[i], capy[i]);
665         if (isod > d)
666             d = isod;
667     }
668
669     for (i = 0; i < STABLE_CYCLE; ++i)
670         if (d != mc[i])
671             stab = 0;
672
673     mc[turns % STABLE_CYCLE] = d;
674     return stab;
675 }
676
677 /* This routine does the actual drifting
678 */
679
680 static void
681 fl_move(int j)
682 {
683     int dir, i, newx, newy;
684
685     dir = DIR_L + roll0(6);
686     for (i = 0; i < 6; i++) {
687         if (dir > DIR_LAST)
688             dir -= 6;
689         newx = new_x(capx[j] + diroff[dir][0]);
690         newy = new_y(capy[j] + diroff[dir][1]);
691         dir++;
692         if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
693             capx[j] = newx;
694             capy[j] = newy;
695             return;
696         }
697     }
698 }
699
700 /****************************************************************************
701   GROW THE CONTINENTS
702 ****************************************************************************/
703
704 /* Look for a coastal sector of continent c
705 */
706
707 static void
708 find_coast(int c)
709 {
710     int i, dir, nx, ny;
711
712     for (i = 0; i < isecs[c]; ++i) {
713         sectc[c][i] = 0;
714         for (dir = DIR_FIRST; dir <= DIR_LAST; dir++) {
715             nx = new_x(sectx[c][i] + diroff[dir][0]);
716             ny = new_y(secty[c][i] + diroff[dir][1]);
717             if (own[nx][ny] == -1)
718                 sectc[c][i] = 1;
719         }
720     }
721 }
722
723 struct hexagon_iter {
724     int dir, i, n;
725 };
726
727 /*
728  * Start iterating around @x0,@y0 at distance @d.
729  * Set *x,*y to coordinates of the first sector.
730  */
731 static inline void
732 hexagon_first(struct hexagon_iter *iter, int x0, int y0, int n,
733               int *x, int *y)
734 {
735     *x = new_x(x0 - 2 * n);
736     *y = y0;
737     iter->dir = DIR_FIRST;
738     iter->i = 0;
739     iter->n = n;
740 }
741
742 /*
743  * Continue iteration started with hexagon_first().
744  * Set *x,*y to coordinates of the next sector.
745  * Return whether we're back at the first sector, i.e. iteration is
746  * complete.
747  */
748 static inline int
749 hexagon_next(struct hexagon_iter *iter, int *x, int *y)
750 {
751     *x = new_x(*x + diroff[iter->dir][0]);
752     *y = new_y(*y + diroff[iter->dir][1]);
753     iter->i++;
754     if (iter->i == iter->n) {
755         iter->i = 0;
756         iter->dir++;
757     }
758     return iter->dir <= DIR_LAST;
759 }
760
761 /*
762  * Is @x,@y in no exclusive zone other than perhaps @c's?
763  */
764 static int
765 xzone_ok(int c, int x, int y)
766 {
767     int off = XYOFFSET(x, y);
768
769     return xzone[off] == c || xzone[off] == -1;
770 }
771
772 /*
773  * Add sectors within distance @dist of @x,@y to @c's exclusive zone.
774  */
775 static void
776 xzone_around_sector(int c, int x, int y, int dist)
777 {
778     int d, x1, y1, off;
779     struct hexagon_iter hexit;
780
781     assert(xzone_ok(c, x, y));
782
783     xzone[XYOFFSET(x, y)] = c;
784     for (d = 1; d <= dist; d++) {
785         hexagon_first(&hexit, x, y, d, &x1, &y1);
786         do {
787             off = XYOFFSET(x1, y1);
788             if (xzone[off] == -1)
789                 xzone[off] = c;
790             else if (xzone[off] != c)
791                 xzone[off] = -2;
792         } while (hexagon_next(&hexit, &x1, &y1));
793     }
794 }
795
796 /*
797  * Add sectors within distance @dist to island @c's exclusive zone.
798  */
799 static void
800 xzone_around_island(int c, int dist)
801 {
802     int i;
803
804     for (i = 0; i < isecs[c]; i++)
805         xzone_around_sector(c, sectx[c][i], secty[c][i], dist);
806 }
807
808 /*
809  * Initialize exclusive zones around @n islands.
810  */
811 static void
812 xzone_init(int n)
813 {
814     int i, c;
815
816     for (i = 0; i < WORLD_SZ(); i++)
817         xzone[i] = -1;
818
819     for (c = 0; c < n; c++)
820         xzone_around_island(c, id);
821 }
822
823 /*
824  * Initialize breadth-first search.
825  */
826 static void
827 bfs_init(void)
828 {
829     int i;
830
831     for (i = 0; i < WORLD_SZ(); i++) {
832         closest[i] = -1;
833         distance[i] = USHRT_MAX;
834     }
835
836     bfs_queue_head = bfs_queue_tail = 0;
837 }
838
839 /*
840  * Add sector @x,@y to the BFS queue.
841  * It's closest to @c, with distance @dist.
842  */
843 static void
844 bfs_enqueue(int c, int x, int y, int dist)
845 {
846     int off = XYOFFSET(x, y);
847
848     assert(dist < distance[off]);
849     closest[off] = c;
850     distance[off] = dist;
851     bfs_queue[bfs_queue_tail] = off;
852     bfs_queue_tail++;
853     if (bfs_queue_tail >= WORLD_SZ())
854         bfs_queue_tail = 0;
855     assert(bfs_queue_tail != bfs_queue_head);
856 }
857
858 /*
859  * Search breadth-first until the queue is empty.
860  */
861 static void
862 bfs_run_queue(void)
863 {
864     int off, dist, i, noff, nx, ny;
865     coord x, y;
866
867     while (bfs_queue_head != bfs_queue_tail) {
868         off = bfs_queue[bfs_queue_head];
869         bfs_queue_head++;
870         if (bfs_queue_head >= WORLD_SZ())
871             bfs_queue_head = 0;
872         dist = distance[off] + 1;
873         sctoff2xy(&x, &y, off);
874         for (i = DIR_FIRST; i <= DIR_LAST; i++) {
875             nx = new_x(x + diroff[i][0]);
876             ny = new_y(y + diroff[i][1]);
877             noff = XYOFFSET(nx, ny);
878             if (dist < distance[noff]) {
879                 bfs_enqueue(closest[off], nx, ny, dist);
880             } else if (distance[noff] == dist) {
881                 if (closest[off] != closest[noff])
882                     closest[noff] = (natid)-1;
883             } else
884                 assert(distance[noff] < dist);
885         }
886     }
887 }
888
889 /*
890  * Add island @c's coastal sectors to the BFS queue, with distance 0.
891  */
892 static void
893 bfs_enqueue_island(int c)
894 {
895     int i;
896
897     for (i = 0; i < isecs[c]; i++) {
898         if (sectc[c][i])
899             bfs_enqueue(c, sectx[c][i], secty[c][i], 0);
900     }
901 }
902
903 /*
904  * Compute spheres of influence
905  * A continent's sphere of influence is the set of sectors closer to
906  * it than to any other continent.
907  * Set closest[XYOFFSET(x, y)] to the closest continent's number,
908  * -1 if no single continent is closest.
909  * Set distance[XYOFFSET(x, y)] to the distance to the closest coastal
910  * land sector.
911  */
912 static void
913 init_spheres_of_influence(void)
914 {
915     int c;
916
917     bfs_init();
918     for (c = 0; c < nc; c++)
919         bfs_enqueue_island(c);
920     bfs_run_queue();
921 }
922
923 /*
924  * Is @x,@y in the same sphere of influence as island @c?
925  * Always true when @c is a continent.
926  */
927 static int
928 is_in_sphere(int c, int x, int y)
929 {
930     return c < nc || closest[XYOFFSET(x, y)] == c % nc;
931 }
932
933 /*
934  * Can island @c grow at @x,@y?
935  */
936 static int
937 can_grow_at(int c, int x, int y)
938 {
939     return own[x][y] == -1 && xzone_ok(c, x, y) && is_in_sphere(c, x, y);
940 }
941
942 static void
943 adj_land_update(int x, int y)
944 {
945     int dir, nx, ny, noff;
946
947     assert(own[x][y] != -1);
948
949     for (dir = DIR_FIRST; dir <= DIR_LAST; dir++) {
950         nx = new_x(x + diroff[dir][0]);
951         ny = new_y(y + diroff[dir][1]);
952         noff = XYOFFSET(nx, ny);
953         adj_land[noff] |= 1u << DIR_BACK(dir);
954     }
955 }
956
957 static void
958 add_sector(int c, int x, int y)
959 {
960     assert(own[x][y] == -1);
961     xzone_around_sector(c, x, y, c < nc ? di : DISTINCT_ISLANDS ? id : 0);
962     sectx[c][isecs[c]] = x;
963     secty[c][isecs[c]] = y;
964     isecs[c]++;
965     own[x][y] = c;
966     adj_land_update(x, y);
967 }
968
969 static int grow_weight(int c, int x, int y, int spike)
970 {
971     int n, b;
972
973     /*
974      * #Land neighbors is #bits set in adj_land[].
975      * Count them Brian Kernighan's way.
976      */
977     n = 0;
978     for (b = adj_land[XYOFFSET(x, y)]; b; b &= b - 1)
979         n++;
980     assert(n > 0 && n < 7);
981
982     if (spike)
983         return (6 - n) * (6 - n);
984
985     return n * n * n;
986 }
987
988 static int
989 grow_one_sector(int c)
990 {
991     int spike = roll0(100) < sp;
992     int wsum, newx, newy, i, x, y, off, dir, nx, ny, noff, w;
993
994     assert(cur_seen < UINT_MAX);
995     cur_seen++;
996     wsum = 0;
997     newx = newy = -1;
998
999     for (i = 0; i < isecs[c]; i++) {
1000         x = sectx[c][i];
1001         y = secty[c][i];
1002         off = XYOFFSET(x, y);
1003
1004         for (dir = DIR_FIRST; dir <= DIR_LAST; dir++) {
1005             if (adj_land[off] & (1u << dir))
1006                 continue;
1007             nx = new_x(x + diroff[dir][0]);
1008             ny = new_y(y + diroff[dir][1]);
1009             noff = XYOFFSET(nx, ny);
1010             if (seen[noff] == cur_seen)
1011                 continue;
1012             assert(seen[noff] < cur_seen);
1013             seen[noff] = cur_seen;
1014             if (!can_grow_at(c, nx, ny))
1015                 continue;
1016             w = grow_weight(c, nx, ny, spike);
1017             assert(wsum < INT_MAX - w);
1018             wsum += w;
1019             if (roll0(wsum) < w) {
1020                 newx = nx;
1021                 newy = ny;
1022             }
1023         }
1024     }
1025
1026     if (!wsum)
1027         return 0;
1028
1029     add_sector(c, newx, newy);
1030     return 1;
1031 }
1032
1033 /*
1034  * Grow the continents.
1035  * Return 1 on success, 0 on error.
1036  */
1037 static int
1038 grow_continents(void)
1039 {
1040     int done = 1;
1041     int c, secs;
1042
1043     xzone_init(0);
1044
1045     for (c = 0; c < nc; ++c) {
1046         isecs[c] = 0;
1047         if (!can_grow_at(c, capx[c], capy[c])
1048             || !can_grow_at(c, new_x(capx[c] + 2), capy[c])) {
1049             done = 0;
1050             continue;
1051         }
1052         add_sector(c, capx[c], capy[c]);
1053         add_sector(c, new_x(capx[c] + 2), capy[c]);
1054     }
1055
1056     if (!done) {
1057         qprint("No room for continents\n");
1058         return 0;
1059     }
1060
1061     for (secs = 2; secs < sc && done; secs++) {
1062         for (c = 0; c < nc; ++c) {
1063             if (!grow_one_sector(c))
1064                 done = 0;
1065         }
1066     }
1067
1068     for (c = 0; c < nc; ++c)
1069         find_coast(c);
1070
1071     if (!done)
1072         qprint("Only managed to grow %d out of %d sectors.\n",
1073                secs - 1, sc);
1074     return done;
1075 }
1076
1077 /****************************************************************************
1078   GROW THE ISLANDS
1079 ****************************************************************************/
1080
1081 /*
1082  * Place additional island @c's first sector.
1083  * Return 1 on success, 0 on error.
1084  */
1085 static int
1086 place_island(int c)
1087 {
1088     int n, x, y, newx, newy;
1089
1090     n = 0;
1091
1092     for (y = 0; y < WORLD_Y; y++) {
1093         for (x = y % 2; x < WORLD_X; x += 2) {
1094             if (can_grow_at(c, x, y)) {
1095                 n++;
1096                 if (!roll0(n)) {
1097                     newx = x;
1098                     newy = y;
1099                 }
1100             }
1101         }
1102     }
1103
1104     if (n)
1105         add_sector(c, newx, newy);
1106     return n;
1107 }
1108
1109 /*
1110  * Grow the additional islands.
1111  * Return 1 on success, 0 on error.
1112  */
1113 static int
1114 grow_islands(void)
1115 {
1116     int stunted_islands = 0;
1117     int c, secs, isiz;
1118
1119     xzone_init(nc);
1120     init_spheres_of_influence();
1121
1122     for (c = nc; c < nc + ni; ++c) {
1123         isecs[c] = 0;
1124
1125         if (!place_island(c)) {
1126             qprint("\nNo room for island #%d", c - nc + 1);
1127             break;
1128         }
1129
1130         isiz = roll(is) + roll0(is);
1131         for (secs = 1; secs < isiz; secs++) {
1132             if (!grow_one_sector(c)) {
1133                 stunted_islands++;
1134                 break;
1135             }
1136         }
1137
1138         find_coast(c);
1139         qprint(" %d(%d)", c - nc + 1, secs);
1140     }
1141
1142     qprint("\n");
1143
1144     if (c < nc + ni)
1145         return 0;
1146
1147     if (stunted_islands)
1148         qprint("%d stunted island%s\n",
1149                stunted_islands, splur(stunted_islands));
1150     return 1;
1151 }
1152
1153 /****************************************************************************
1154   CREATE ELEVATIONS
1155 ****************************************************************************/
1156 static void
1157 create_elevations(void)
1158 {
1159     int i, j;
1160
1161     for (i = 0; i < WORLD_X; i++) {
1162         for (j = 0; j < WORLD_Y; j++)
1163             elev[i][j] = -INFINITE_ELEVATION;
1164     }
1165     elevate_land();
1166     elevate_sea();
1167 }
1168
1169 /* Generic function for finding the distance to the closest sea, land, or
1170    mountain
1171 */
1172 static int
1173 distance_to_what(int x, int y, int flag)
1174 {
1175     int d, px, py;
1176     struct hexagon_iter hexit;
1177
1178     for (d = 1; d < 5; ++d) {
1179         hexagon_first(&hexit, x, y, d, &px, &py);
1180         do {
1181             switch (flag) {
1182             case 0:             /* distance to sea */
1183                 if (own[px][py] == -1)
1184                     return d;
1185                 break;
1186             case 1:             /* distance to land */
1187                 if (own[px][py] != -1)
1188                     return d;
1189                 break;
1190             case 2:             /* distance to mountain */
1191                 if (elev[px][py] == INFINITE_ELEVATION)
1192                     return d;
1193                 break;
1194             }
1195         } while (hexagon_next(&hexit, &px, &py));
1196     }
1197     return d;
1198 }
1199
1200 #define ELEV elev[sectx[c][i]][secty[c][i]]
1201 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
1202 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
1203
1204 /* Decide where the mountains go
1205 */
1206 static void
1207 elevate_land(void)
1208 {
1209     int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
1210         r, dk;
1211
1212     for (c = 0; c < nc + ni; ++c) {
1213         total = 0;
1214         ns = isecs[c];
1215         nm = (pm * ns) / 100;
1216
1217 /* Place the mountains */
1218
1219         for (i = 0; i < ns; ++i) {
1220             dsea[i] = distance_to_sea();
1221             weight[i] = (total += (dsea[i] * dsea[i]));
1222         }
1223
1224         for (k = nm, mountain_search = 0;
1225              k && mountain_search < MOUNTAIN_SEARCH_MAX;
1226              ++mountain_search) {
1227             r = roll0(total);
1228             for (i = 0; i < ns; ++i)
1229                 if (r < weight[i] && ELEV == -INFINITE_ELEVATION &&
1230                     (c >= nc ||
1231                      ((!(capx[c] == sectx[c][i] &&
1232                          capy[c] == secty[c][i])) &&
1233                       (!(new_x(capx[c] + 2) == sectx[c][i] &&
1234                          capy[c] == secty[c][i]))))) {
1235                     ELEV = INFINITE_ELEVATION;
1236                     break;
1237                 }
1238             --k;
1239         }
1240
1241 /* Elevate land that is not mountain and not capital */
1242
1243         for (i = 0; i < ns; ++i)
1244             dmoun[i] = distance_to_mountain();
1245         dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
1246           (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
1247           100 * INFINITE_ELEVATION;
1248         for (k = 100 * (HIGHMIN - 1);; k -= dk) {
1249             highest = 0;
1250             where = -1;
1251             for (i = 0; i < ns; ++i) {
1252                 if (ELEV == -INFINITE_ELEVATION &&
1253                     (c >= nc || ((!(capx[c] == sectx[c][i] &&
1254                                     capy[c] == secty[c][i])) &&
1255                                  (!(new_x(capx[c] + 2) == sectx[c][i] &&
1256                                     capy[c] == secty[c][i]))))) {
1257                     h = 3 * (5 - dmoun[i]) + dsea[i];
1258                     assert(h > 0);
1259                     if (h > highest) {
1260                         highest = h;
1261                         where = i;
1262                     }
1263                 }
1264             }
1265             if (where == -1)
1266                 break;
1267             newk = k / 100;
1268             if (newk >= HILLMIN && newk < PLATMIN)
1269                 newk = PLATMIN;
1270             if (newk < LANDMIN)
1271                 newk = LANDMIN;
1272             elev[sectx[c][where]][secty[c][where]] = newk;
1273         }
1274
1275 /* Elevate the mountains and capitals */
1276
1277         for (i = 0; i < ns; ++i) {
1278             if (ELEV == INFINITE_ELEVATION) {
1279                 if (dsea[i] == 1)
1280                     ELEV = HILLMIN + roll0(PLATMIN - HILLMIN);
1281                 else
1282                     ELEV = HIGHMIN + roll0((256 - HIGHMIN) / 2) +
1283                       roll0((256 - HIGHMIN) / 2);
1284             } else if (c < nc &&
1285                        (((capx[c] == sectx[c][i] && capy[c] == secty[c][i])) ||
1286                         ((new_x(capx[c] + 2) == sectx[c][i] &&
1287                           capy[c] == secty[c][i]))))
1288                 ELEV = PLATMIN;
1289         }
1290     }
1291 }
1292
1293 #define distance_to_land() distance_to_what(x, y, 1)
1294
1295 static void
1296 elevate_sea(void)
1297 {
1298     int x, y;
1299
1300     for (y = 0; y < WORLD_Y; ++y) {
1301         for (x = y % 2; x < WORLD_X; x += 2) {
1302             if (elev[x][y] == -INFINITE_ELEVATION)
1303                 elev[x][y] = -roll(distance_to_land() * 20 + 27);
1304         }
1305     }
1306 }
1307
1308 static int
1309 elev_to_sct_type(int elevation)
1310 {
1311     if (elevation < LANDMIN)
1312         return SCT_WATER;
1313     if (elevation < HILLMIN)
1314         return SCT_RURAL;
1315     if (elevation < PLATMIN)
1316         return SCT_MOUNT;
1317     if (elevation < HIGHMIN)
1318         return SCT_RURAL;
1319     return SCT_MOUNT;
1320 }
1321
1322 /****************************************************************************
1323   ADD THE RESOURCES
1324 ****************************************************************************/
1325
1326 static int
1327 set_fert(int e)
1328 {
1329     int fert = 0;
1330     if (e < LANDMIN)
1331         fert = LANDMIN - e + 40;
1332     else if (e < FERT_MAX)
1333         fert = (120 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
1334     if (fert > 100)
1335         fert = 100;
1336     return fert;
1337 }
1338
1339 static int
1340 set_oil(int e)
1341 {
1342     int oil = 0;
1343     if (e < LANDMIN)
1344         oil = (LANDMIN - e) * 2 + roll0(2);
1345     else if (e <= OIL_MAX)
1346         oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1347     if (oil > 100)
1348         oil = 100;
1349     return oil;
1350 }
1351
1352 static int
1353 set_iron(int e)
1354 {
1355     int iron = 0;
1356     if (e >= IRON_MIN && e < HIGHMIN)
1357         iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1358     if (iron > 100)
1359         iron = 100;
1360     return iron;
1361 }
1362
1363 static int
1364 set_gold(int e)
1365 {
1366     int gold = 0;
1367     if (e >= GOLD_MIN) {
1368         if (e < HIGHMIN)
1369             gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1370         else
1371             gold = 100 - 20 * HIGHMIN / e;
1372     }
1373     if (gold > 100)
1374         gold = 100;
1375     return gold;
1376 }
1377
1378 static int
1379 set_uran(int e)
1380 {
1381     int uran = 0;
1382     if (e >= URAN_MIN && e < HIGHMIN)
1383         uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1384     if (uran > 100)
1385         uran = 100;
1386     return uran;
1387 }
1388
1389 static void
1390 add_resources(struct sctstr *sct)
1391 {
1392     sct->sct_fertil = set_fert(sct->sct_elev);
1393     sct->sct_oil = set_oil(sct->sct_elev);
1394     sct->sct_min = set_iron(sct->sct_elev);
1395     sct->sct_gmin = set_gold(sct->sct_elev);
1396     sct->sct_uran = set_uran(sct->sct_elev);
1397 }
1398
1399 /****************************************************************************
1400   DESIGNATE THE SECTORS
1401 ****************************************************************************/
1402
1403 static void
1404 write_sects(void)
1405 {
1406     struct sctstr *sct;
1407     int x, y;
1408
1409     for (y = 0; y < WORLD_Y; y++) {
1410         for (x = y % 2; x < WORLD_X; x += 2) {
1411             sct = getsectp(x, y);
1412             sct->sct_elev = elev[x][y];
1413             sct->sct_type = elev_to_sct_type(elev[x][y]);
1414             sct->sct_newtype = sct->sct_type;
1415             sct->sct_dterr = own[sct->sct_x][y] + 1;
1416             add_resources(sct);
1417         }
1418     }
1419     set_coastal_flags();
1420 }
1421
1422 /****************************************************************************
1423   PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1424 ****************************************************************************/
1425 static void
1426 output(void)
1427 {
1428     int sx, sy, x, y, c, type;
1429
1430     if (quiet == 0) {
1431         for (sy = -WORLD_Y / 2; sy < WORLD_Y / 2; sy++) {
1432             y = YNORM(sy);
1433             puts("");
1434             if (y % 2)
1435                 printf(" ");
1436             for (sx = -WORLD_X / 2 + y % 2; sx < WORLD_X / 2; sx += 2) {
1437                 x = XNORM(sx);
1438                 c = own[x][y];
1439                 type = elev_to_sct_type(elev[x][y]);
1440                 if (type == SCT_WATER)
1441                     printf(". ");
1442                 else if (type == SCT_MOUNT)
1443                     printf("^ ");
1444                 else if (c >= nc)
1445                     printf("%% ");
1446                 else {
1447                     assert(0 <= c && c < nc);
1448                     if ((x == capx[c] || x == new_x(capx[c] + 2))
1449                         && y == capy[c])
1450                         printf("%c ", numletter[c % 62]);
1451                     else
1452                         printf("# ");
1453                 }
1454             }
1455         }
1456     }
1457 }
1458
1459 /*
1460  * Print a map to help visualize own[][].
1461  * This is for debugging.
1462  */
1463 void
1464 print_own_map(void)
1465 {
1466     int sx, sy, x, y;
1467
1468     for (sy = -WORLD_Y / 2; sy < WORLD_Y / 2; sy++) {
1469         y = YNORM(sy);
1470         printf("%4d ", sy);
1471         for (sx = -WORLD_X / 2; sx < WORLD_X / 2; sx++) {
1472             x = XNORM(sx);
1473             if ((x + y) & 1)
1474                 putchar(' ');
1475             else if (own[x][y] == -1)
1476                 putchar('.');
1477             else
1478                 putchar(numletter[own[x][y] % 62]);
1479         }
1480         putchar('\n');
1481     }
1482 }
1483
1484 /*
1485  * Print a map to help visualize elev[][].
1486  * This is for debugging.  It expects the terminal to understand
1487  * 24-bit color escape sequences \e[48;2;$red;$green;$blue;m.
1488  */
1489 void
1490 print_elev_map(void)
1491 {
1492     int sx, sy, x, y, sat;
1493
1494     for (sy = -WORLD_Y / 2; sy < WORLD_Y / 2; sy++) {
1495         y = YNORM(sy);
1496         printf("%4d ", sy);
1497         for (sx = -WORLD_X / 2; sx < WORLD_X / 2; sx++) {
1498             x = XNORM(sx);
1499             if ((x + y) & 1)
1500                 putchar(' ');
1501             else if (!elev[x][y])
1502                 putchar(' ');
1503             else if (elev[x][y] < 0) {
1504                 sat = 256 + elev[x][y] * 2;
1505                 printf("\033[48;2;%d;%d;%dm \033[0m", sat, sat, 255);
1506             } else if (elev[x][y] < HIGHMIN / 2) {
1507                 sat = (HIGHMIN / 2 - elev[x][y]) * 4;
1508                 printf("\033[48;2;%d;%d;%dm \033[0m", sat, 255, sat);
1509             } else if (elev[x][y] < HIGHMIN) {
1510                 sat = 128 + (HIGHMIN - elev[x][y]) * 2;
1511                 printf("\033[48;2;%d;%d;%dm \033[0m", sat, sat / 2, sat / 4);
1512             } else {
1513                 sat = 128 + (elev[x][y] - HIGHMIN) * 4 / 5;
1514                 printf("\033[48;2;%d;%d;%dm^\033[0m", sat, sat, sat);
1515             }
1516         }
1517         putchar('\n');
1518     }
1519 }
1520
1521 /*
1522  * Print a map to help visualize xzone[].
1523  * This is for debugging.
1524  */
1525 void
1526 print_xzone_map(void)
1527 {
1528     int sx, sy, x, y, off;
1529
1530     for (sy = -WORLD_Y / 2; sy < WORLD_Y / 2; sy++) {
1531         y = YNORM(sy);
1532         printf("%4d ", sy);
1533         for (sx = -WORLD_X / 2; sx < WORLD_X / 2; sx++) {
1534             x = XNORM(sx);
1535             off = XYOFFSET(x, y);
1536             if ((x + y) & 1)
1537                 putchar(' ');
1538             else if (own[x][y] >= 0)
1539                 putchar('-');
1540             else if (xzone[off] >= 0)
1541                 putchar(numletter[xzone[off] % 62]);
1542             else {
1543                 assert(own[x][y] == -1);
1544                 putchar(xzone[off] == -1 ? '.' : '!');
1545             }
1546         }
1547         putchar('\n');
1548     }
1549 }
1550
1551 /*
1552  * Print a map to help visualize closest[].
1553  * This is for debugging.
1554  */
1555 void
1556 print_closest_map(void)
1557 {
1558     int sx, sy, x, y, off;
1559
1560     for (sy = -WORLD_Y / 2; sy < WORLD_Y / 2; sy++) {
1561         y = YNORM(sy);
1562         printf("%4d ", sy);
1563         for (sx = -WORLD_X / 2; sx < WORLD_X / 2; sx++) {
1564             x = XNORM(sx);
1565             off = XYOFFSET(x, y);
1566             if ((x + y) & 1)
1567                 putchar(' ');
1568             else if (closest[off] == (natid)-1)
1569                 putchar('.');
1570             else if (!distance[off]) {
1571                 assert(closest[off] == own[x][y]);
1572                 putchar('-');
1573             } else {
1574                 putchar(numletter[closest[off] % 62]);
1575             }
1576         }
1577         printf("\n");
1578     }
1579 }
1580
1581 void
1582 print_distance_map(void)
1583 {
1584     int sx, sy, x, y, off;
1585
1586     for (sy = -WORLD_Y / 2; sy < WORLD_Y / 2; sy++) {
1587         y = YNORM(sy);
1588         printf("%4d ", sy);
1589         for (sx = -WORLD_X / 2; sx < WORLD_X / 2; sx++) {
1590             x = XNORM(sx);
1591             off = XYOFFSET(x, y);
1592             if ((x + y) & 1)
1593                 putchar(' ');
1594             else if (closest[off] == (natid)-1)
1595                 putchar('.');
1596             else if (!distance[off]) {
1597                 assert(closest[off] == own[x][y]);
1598                 putchar('-');
1599             } else {
1600                 putchar(numletter[distance[off] % 62]);
1601             }
1602         }
1603         printf("\n");
1604     }
1605 }
1606
1607
1608 /***************************************************************************
1609   WRITE A SCRIPT FOR PLACING CAPITALS
1610 ****************************************************************************/
1611 static int
1612 write_newcap_script(void)
1613 {
1614     int c;
1615     FILE *script = fopen(outfile, "w");
1616
1617     if (!script) {
1618         fprintf(stderr, "%s: unable to write to %s (%s)\n",
1619                 program_name, outfile, strerror(errno));
1620         return 0;
1621     }
1622
1623     for (c = 0; c < nc; ++c) {
1624         fprintf(script, "add %d %d %d p\n", c + 1, c + 1, c + 1);
1625         fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1626     }
1627     fprintf(script, "add %d visitor visitor v\n", c + 1);
1628     fclose(script);
1629     return 1;
1630 }
1631
1632 static void
1633 qprint(const char *const fmt, ...)
1634 {
1635     va_list ap;
1636
1637     if (!quiet) {
1638         va_start(ap, fmt);
1639         vfprintf(stdout, fmt, ap);
1640         va_end(ap);
1641     }
1642 }
1643
1644 static void
1645 set_coastal_flags(void)
1646 {
1647     int i, j;
1648     struct sctstr *sp;
1649
1650     for (i = 0; i < nc + ni; ++i) {
1651         for (j = 0; j < isecs[i]; j++) {
1652             sp = getsectp(sectx[i][j], secty[i][j]);
1653             sp->sct_coastal = sectc[i][j];
1654         }
1655     }
1656 }