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