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