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