2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2013, Dave Pare, Jeff Bailey, Thomas Ruschak,
4 * Ken Stevens, Steve McClure, Markus Armbruster
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.
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.
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/>.
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.
27 * fairland.c: Create a nice, new world
29 * Known contributors to this file:
32 * Markus Armbruster, 2004-2012
37 /* define ORE 1 to add resources, define ORE 0 if you want to use another
38 program to add the resources */
42 /* If you don't specify these command line arguments, then these are the
44 #define DEFAULT_SPIKE 10
45 #define DEFAULT_MOUNTAIN 0
46 #define DEFAULT_CONTDIST 2
47 #define DEFAULT_ISLDIST 1
49 /* The following five numbers refer to elevation under which (in the case of
50 fertility or oil) or over which (in the case of iron, gold, and uranium)
51 sectors with that elevation will contain that resource. Elevation ranges
54 /* raise FERT_MAX for more fertility */
57 /* raise OIL_MAX for more oil */
60 /* lower IRON_MIN for more iron */
63 /* lower GOLD_MIN for more gold */
66 /* lower URAN_MIN for more uranium */
77 #include "prototypes.h"
82 /* do not change these 4 defines */
83 #define LANDMIN 1 /* plate altitude for normal land */
84 #define HILLMIN 34 /* plate altitude for hills */
85 #define PLATMIN 36 /* plate altitude for plateau */
86 #define HIGHMIN 98 /* plate altitude for mountains */
88 static void qprint(const char * const fmt, ...)
89 ATTRIBUTE((format (printf, 1, 2)));
91 #define DEFAULT_OUTFILE_NAME "newcap_script"
92 static const char *outfile = DEFAULT_OUTFILE_NAME;
93 /* mark the continents with a * so you can tell them
94 from the islands 1 = mark, 0 = don't mark. */
95 static int AIRPORT_MARKER = 0;
97 /* don't let the islands crash into each other.
98 1 = don't merge, 0 = merge. */
99 static int DISTINCT_ISLANDS = 1;
101 static char *program_name;
103 #define STABLE_CYCLE 4 /* stability required for perterbed capitals */
104 #define INFINITY 999 /* a number which means "BIG" */
106 /* these defines prevent infinite loops:
109 #define COAST_SEARCH_MAX 200 /* how many times do we look for a coast sector
110 when growing continents and islands */
111 #define DRIFT_BEFORE_CHECK ((WORLD_X + WORLD_Y)/2)
112 #define DRIFT_MAX ((WORLD_X + WORLD_Y)*2)
113 #define MOUNTAIN_SEARCH_MAX 1000 /* how long do we try to place mountains */
118 #define new_x(newx) (((newx) + WORLD_X) % WORLD_X)
119 #define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y)
121 static int secs; /* number of sectors grown */
122 static int ctot; /* total number of continents and islands grown */
123 static int *isecs; /* array of how large each island is */
125 static int nc, sc, di, sp, pm, ni, is, id; /* the 8 args to this program */
126 static int *capx, *capy; /* location of the nc capitals */
127 static int *mc, mcc; /* array and counter used for stability
128 check when perturbing */
129 static int spike; /* are we spiking? */
130 static int mind; /* the final distance between capitals that
132 static int dirx[] = { -2, -1, 1, 2, 1, -1 }; /* gyujnb */
133 static int diry[] = { 0, -1, -1, 0, 1, 1 };
135 static int **own; /* owner of the sector. -1 means water */
136 static int **elev; /* elevation of the sectors */
137 static int **sectx, **secty; /* the sectors for each continent */
138 static int **sectc; /* which sectors are on the coast? */
139 static int *vector; /* used for measuring distances */
140 static int *weight; /* used for placing mountains */
141 static int *dsea, *dmoun; /* the dist to the ocean and mountain */
142 static int fl_status; /* is anything wrong? */
143 #define STATUS_NO_ROOM 1 /* there was no room to grow */
144 #define NUMTRIES 10 /* keep trying to grow this many times */
146 static const char *numletter =
147 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
149 static void help(char *);
150 static void usage(void);
151 static void parse_args(int argc, char *argv[]);
152 static void allocate_memory(void);
153 static void init(void);
154 static int drift(void);
155 static void grow_continents(void);
156 static void create_elevations(void);
157 static void write_sects(void);
158 static void output(void);
159 static int write_newcap_script(void);
160 static int stable(void);
161 static void elevate_land(void);
162 static void elevate_sea(void);
163 static int map_symbol(int x, int y);
164 static void set_coastal_flags(void);
166 static void print_vars(void);
167 static void fl_move(int);
168 static void grow_islands(void);
170 /****************************************************************************
172 ****************************************************************************/
175 main(int argc, char *argv[])
178 char *config_file = NULL;
180 unsigned rnd_seed = 0;
183 program_name = argv[0];
185 while ((opt = getopt(argc, argv, "ae:hioqR:s:v")) != EOF) {
191 config_file = optarg;
194 DISTINCT_ISLANDS = 0;
203 rnd_seed = strtoul(optarg, NULL, 10);
213 printf("%s\n\n%s", version, legal);
220 parse_args(argc - optind, argv + optind);
223 rnd_seed = pick_seed();
226 if (emp_config(config_file) < 0)
233 qprint("\n #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
234 qprint("seed is %u\n", rnd_seed);
238 qprint("\ntry #%d (out of %d)...\n", i + 1, NUMTRIES);
239 qprint("placing capitals...\n");
241 qprint("fairland: unstable drift -- try increasisg DRIFT_MAX\n");
242 qprint("growing continents...\n");
244 } while (fl_status && ++i < NUMTRIES);
246 fputs("ERROR: World not large enough to hold continents\n",
250 qprint("growing islands:");
252 qprint("\nelevating land...\n");
254 qprint("designating sectors...\n");
256 qprint("adding resources...\n");
257 write_newcap_script();
259 if (chdir(gamedir)) {
260 fprintf(stderr, "Can't chdir to %s (%s)\n", gamedir, strerror(errno));
263 if (!ef_open(EF_SECTOR, EFF_MEM | EFF_NOTIME))
266 qprint("writing to sectors file...\n");
267 if (!ef_close(EF_SECTOR))
271 qprint("\n\nA script for adding all the countries can be found in \"%s\".\n",
274 qprint("\t*** Resources have not been added ***\n");
283 puts("Creating a planet with:\n");
284 printf("%d continents\n", nc);
285 printf("continent size: %d\n", sc);
286 printf("number of islands: %d\n", ni);
287 printf("average size of islands: %d\n", is);
288 printf("spike: %d%%\n", sp);
289 printf("%d%% of land is mountain (each continent will have %d mountains)\n",
290 pm, (pm * sc) / 100);
291 printf("minimum distance between continents: %d\n", di);
292 printf("minimum distance from islands to continents: %d\n", id);
293 printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
301 for (i = 1; i * i < n * 10000; ++i) ;
302 return (i + 50) / 100;
305 /****************************************************************************
306 PARSE COMMAND LINE ARGUMENTS
307 ****************************************************************************/
310 help(char *complaint)
313 fprintf(stderr, "%s: %s\n", program_name, complaint);
314 fprintf(stderr, "Try -h for help.\n");
320 printf("Usage: %s [OPTION]... NC SC [NI] [IS] [SP] [PM] [DI] [ID]\n"
321 " -a airport marker for continents\n"
322 " -e CONFIG-FILE configuration file\n"
324 " -h display this help and exit\n"
325 " -i islands may merge\n"
326 " -o don't set resources\n"
328 " -R SEED seed for random number generator\n"
329 " -s SCRIPT name of script to create (default %s)\n"
330 " NC number of continents\n"
331 " SC continent size\n"
332 " NI number of islands (default NC)\n"
333 " IS average island size (default SC/2)\n"
334 " SP spike percentage: 0 = round, 100 = snake (default %d)\n"
335 " PM percentage of land that is mountain (default %d)\n"
336 " DI minimum distance between continents (default %d)\n"
337 " ID minimum distance from islands to continents (default %d)\n",
338 program_name, dflt_econfig, DEFAULT_OUTFILE_NAME,
339 DEFAULT_SPIKE, DEFAULT_MOUNTAIN, DEFAULT_CONTDIST, DEFAULT_ISLDIST);
343 parse_args(int argc, char *argv[])
346 help("missing arguments");
350 help("too many arguments");
355 puts("fairland: error -- number of continents must be > 0");
361 puts("fairland: error -- size of continents must be > 0");
389 pm = DEFAULT_MOUNTAIN;
396 di = DEFAULT_CONTDIST;
399 puts("fairland: error -- distance between continents must be >= 0");
402 if (di > WORLD_X / 2 || di > WORLD_Y / 2) {
403 puts("fairland: error -- distance between continents too large");
410 id = DEFAULT_ISLDIST;
412 puts("fairland: error -- distance from islands to continents must be >= 0");
415 if (id > WORLD_X || id > WORLD_Y) {
416 puts("fairland: error -- distance from islands to continents too large");
419 if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
420 puts("fairland: warning -- world might be too small to fit continents.");
421 puts("arguments should satisfy:");
422 puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
426 /****************************************************************************
427 VARIABLE INITIALIZATION
428 ****************************************************************************/
431 allocate_memory(void)
435 capx = calloc(nc, sizeof(int));
436 capy = calloc(nc, sizeof(int));
437 vector = calloc(WORLD_X + WORLD_Y, sizeof(int));
438 mc = calloc(STABLE_CYCLE, sizeof(int));
439 own = calloc(WORLD_X, sizeof(int *));
440 elev = calloc(WORLD_X, sizeof(int *));
441 for (i = 0; i < WORLD_X; ++i) {
442 own[i] = calloc(WORLD_Y, sizeof(int));
443 elev[i] = calloc(WORLD_Y, sizeof(int));
445 sectx = calloc(nc + ni, sizeof(int *));
446 secty = calloc(nc + ni, sizeof(int *));
447 sectc = calloc(nc + ni, sizeof(int *));
448 isecs = calloc(nc + ni, sizeof(int));
449 weight = calloc(MAX(sc, is * 2), sizeof(int));
450 dsea = calloc(MAX(sc, is * 2), sizeof(int));
451 dmoun = calloc(MAX(sc, is * 2), sizeof(int));
452 for (i = 0; i < nc; ++i) {
453 sectx[i] = calloc(sc, sizeof(int));
454 secty[i] = calloc(sc, sizeof(int));
455 sectc[i] = calloc(sc, sizeof(int));
457 for (i = nc; i < nc + ni; ++i) {
458 sectx[i] = calloc(is * 2, sizeof(int));
459 secty[i] = calloc(is * 2, sizeof(int));
460 sectc[i] = calloc(is * 2, sizeof(int));
468 int i, j, xx = 0, yy = 0;
473 for (i = 0; i < WORLD_X; ++i) {
474 for (j = 0; j < WORLD_Y; ++j) {
476 elev[i][j] = -INFINITY;
480 for (i = 0; i < nc; ++i) {
485 puts("fairland error: world not big enough for all the continents.\n");
493 for (i = 0; i < STABLE_CYCLE; ++i)
497 /****************************************************************************
498 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
499 ****************************************************************************/
501 /* How isolated is capital j?
504 iso(int j, int newx, int newy)
506 int i, md, d = WORLD_X + WORLD_Y;
508 for (i = 0; i < nc; ++i) {
511 md = mapdist(capx[i], capy[i], newx, newy);
519 /* Drift all the capitals
526 for (turns = 0; turns < DRIFT_MAX; ++turns) {
527 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
529 for (i = 0; i < nc; ++i)
535 /* Check to see if we have stabilized--can we stop drifting the capitals?
541 int i, isod, d = 0, stab = 1;
543 for (i = 0; i < nc; ++i) {
544 isod = iso(i, capx[i], capy[i]);
548 for (i = 0; i < STABLE_CYCLE; ++i)
552 mcc = (mcc + 1) % STABLE_CYCLE;
556 /* This routine does the actual drifting
562 int i, n, newx, newy;
564 for (i = roll0(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
565 newx = new_x(capx[j] + dirx[i]);
566 newy = new_y(capy[j] + diry[i]);
567 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
575 /****************************************************************************
577 ****************************************************************************/
579 /* Look for a coastal sector of continent c
587 for (i = 0; i < secs; ++i) {
589 for (j = 0; j < 6; ++j)
590 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
595 /* Used for measuring distances
607 for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
610 return i > 1 || vector[0] > 0;
613 /* Test to see if we're allowed to grow there: the arguments di and id
616 try_to_grow(int c, int newx, int newy, int d)
620 for (i = 1; i <= d; ++i) {
621 for (j = 0; j < i; ++j)
626 for (j = 0; j < i; ++j) {
627 px = new_x(px + dirx[vector[j]]);
628 py = new_y(py + diry[vector[j]]);
630 if (own[px][py] != -1 &&
632 (DISTINCT_ISLANDS || own[px][py] < nc))
634 } while (next_vector(i));
636 sectx[c][secs] = newx;
637 secty[c][secs] = newy;
642 /* Move along the coast in a clockwise direction.
646 next_coast(int c, int x, int y, int *xp, int *yp)
648 int i, nx, ny, wat = 0;
656 for (i = 0; i < 12; ++i) {
657 nx = new_x(x + dirx[i % 6]);
658 ny = new_y(y + diry[i % 6]);
659 if (own[nx][ny] == -1)
661 if (wat && own[nx][ny] == c) {
669 /* Choose a sector to grow from
681 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : roll0(secs);
686 } while (i != starti);
693 /* Grow continent c by 1 sector
697 grow_one_sector(int c)
699 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
701 spike = roll0(100) < sp;
702 if ((try1 = new_try(c)) == -1)
704 x = sx = sectx[c][try1];
705 y = sy = secty[c][try1];
710 for (i = roll0(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
711 newx = new_x(x + dirx[i]);
712 newy = new_y(y + diry[i]);
713 if (own[newx][newy] == -1 &&
715 (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
716 own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
717 if (try_to_grow(c, newx, newy, c < nc ? di : id))
721 for (i = roll0(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
722 newx = new_x(x + dirx[i]);
723 newy = new_y(y + diry[i]);
724 if (own[newx][newy] == -1)
725 if (try_to_grow(c, newx, newy, c < nc ? di : id))
728 next_coast(c, x, y, &x, &y);
730 } while (!done && coast_search < COAST_SEARCH_MAX &&
731 (secs == 1 || x != sx || y != sy));
732 if (!done && c < nc) {
733 qprint("fairland: error -- continent %c had no room to grow!\n",
735 fl_status |= STATUS_NO_ROOM;
740 /* Grow all the continents
743 grow_continents(void)
747 for (c = 0; c < nc; ++c) {
748 sectx[c][0] = capx[c];
749 secty[c][0] = capy[c];
750 own[sectx[c][0]][secty[c][0]] = c;
751 sectx[c][1] = new_x(capx[c] + 2);
752 secty[c][1] = capy[c];
753 own[sectx[c][1]][secty[c][1]] = c;
756 for (secs = 2; secs < sc && !fl_status; ++secs) {
757 for (c = 0; c < nc; ++c) {
762 for (c = 0; c < nc; ++c)
766 qprint("Only managed to grow %d out of %d sectors.\n", secs, sc);
770 /****************************************************************************
772 ****************************************************************************/
774 /* Choose a place to start growing an island from
777 place_island(int c, int *xp, int *yp)
780 int ssy = roll0(WORLD_Y);
781 int ssx = new_x(roll0(WORLD_X / 2) * 2 + ssy % 2);
783 if (ssx > WORLD_X - 2)
784 ssx = new_x(ssx + 2);
785 for (d = di + id; d >= id; --d) {
789 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
790 if (*xp >= WORLD_X) {
791 *yp = new_y(*yp + 1);
793 if (*xp == sx && *yp == sy)
796 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
803 /* Grow all the islands
811 for (c = nc; c < nc + ni; ++c) {
813 if (!place_island(c, &x, &y))
815 isiz = roll(2 * is - 1);
819 } while (secs < isiz && grow_one_sector(c));
821 qprint(" %d(%d)", c - nc + 1, secs);
827 /****************************************************************************
829 ****************************************************************************/
831 create_elevations(void)
837 /* Generic function for finding the distance to the closest sea, land, or
841 distance_to_what(int x, int y, int flag)
845 for (d = 1; d < 5; ++d) {
846 for (j = 0; j < d; ++j)
851 for (j = 0; j < d; ++j) {
852 px = new_x(px + dirx[vector[j]]);
853 py = new_y(py + diry[vector[j]]);
856 case 0: /* distance to sea */
857 if (own[px][py] == -1)
860 case 1: /* distance to land */
861 if (own[px][py] != -1)
864 case 2: /* distance to mountain */
865 if (elev[px][py] == INFINITY)
869 } while (next_vector(d));
874 #define ELEV elev[sectx[c][i]][secty[c][i]]
875 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
876 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
878 /* Decide where the mountains go
883 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
886 for (c = 0; c < ctot; ++c) {
888 ns = (c < nc) ? sc : isecs[c];
889 nm = (pm * ns) / 100;
891 /* Place the mountains */
893 for (i = 0; i < ns; ++i) {
894 dsea[i] = distance_to_sea();
895 weight[i] = (total += (dsea[i] * dsea[i]));
898 for (k = nm, mountain_search = 0;
899 k && mountain_search < MOUNTAIN_SEARCH_MAX;
902 for (i = 0; i < ns; ++i)
903 if (r < weight[i] && ELEV == -INFINITY &&
905 ((!(capx[c] == sectx[c][i] &&
906 capy[c] == secty[c][i])) &&
907 (!(new_x(capx[c] + 2) == sectx[c][i] &&
908 capy[c] == secty[c][i]))))) {
915 /* Elevate land that is not mountain and not capital */
917 for (i = 0; i < ns; ++i)
918 dmoun[i] = distance_to_mountain();
919 dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
920 (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
922 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
925 for (i = 0; i < ns; ++i) {
926 if (ELEV != INFINITY &&
927 (c >= nc || ((!(capx[c] == sectx[c][i] &&
928 capy[c] == secty[c][i])) &&
929 (!(new_x(capx[c] + 2) == sectx[c][i] &&
930 capy[c] == secty[c][i]))))) {
931 h = 3 * (5 - dmoun[i]) + dsea[i];
941 if (newk >= HILLMIN && newk < PLATMIN)
945 elev[sectx[c][where]][secty[c][where]] = newk;
946 dsea[where] = -INFINITY;
947 dmoun[where] = INFINITY;
950 /* Elevate the mountains and capitals */
952 for (i = 0; i < ns; ++i) {
953 if (ELEV == INFINITY) {
955 ELEV = HILLMIN + roll0(PLATMIN - HILLMIN);
957 ELEV = HIGHMIN + roll0((256 - HIGHMIN) / 2) +
958 roll0((256 - HIGHMIN) / 2);
960 (((capx[c] == sectx[c][i] && capy[c] == secty[c][i])) ||
961 ((new_x(capx[c] + 2) == sectx[c][i] &&
962 capy[c] == secty[c][i]))))
968 #define distance_to_land() distance_to_what(x, y, 1)
975 for (y = 0; y < WORLD_Y; ++y) {
976 for (x = y % 2; x < WORLD_X; x += 2) {
977 if (elev[x][y] == -INFINITY)
978 elev[x][y] = -roll(distance_to_land() * 20 + 27);
983 /****************************************************************************
985 ****************************************************************************/
992 fert = LANDMIN - e + 40;
993 else if (e < FERT_MAX)
994 fert = (120 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
1005 oil = (LANDMIN - e) * 2 + roll0(2);
1006 else if (e <= OIL_MAX)
1007 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1017 if (e >= IRON_MIN && e < HIGHMIN)
1018 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1028 if (e >= GOLD_MIN) {
1030 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1032 gold = 100 - 20 * HIGHMIN / e;
1043 if (e >= URAN_MIN && e < HIGHMIN)
1044 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1051 add_resources(struct sctstr *sct)
1053 sct->sct_fertil = set_fert(sct->sct_elev);
1054 sct->sct_oil = set_oil(sct->sct_elev);
1055 sct->sct_min = set_iron(sct->sct_elev);
1056 sct->sct_gmin = set_gold(sct->sct_elev);
1057 sct->sct_uran = set_uran(sct->sct_elev);
1060 /****************************************************************************
1061 DESIGNATE THE SECTORS
1062 ****************************************************************************/
1070 for (y = 0; y < WORLD_Y; y++) {
1071 for (x = y % 2; x < WORLD_X; x += 2) {
1072 sct = getsectp(x, y);
1074 if (total < LANDMIN) {
1075 sct->sct_type = SCT_WATER;
1076 } else if (total < HILLMIN)
1077 sct->sct_type = SCT_RURAL;
1078 else if (total < PLATMIN)
1079 sct->sct_type = SCT_MOUNT;
1080 else if (total < HIGHMIN)
1081 sct->sct_type = SCT_RURAL;
1083 sct->sct_type = SCT_MOUNT;
1084 sct->sct_elev = total;
1085 sct->sct_newtype = sct->sct_type;
1086 sct->sct_dterr = own[sct->sct_x][y] + 1;
1092 for (c = 0; c < nc; ++c) {
1093 sct = getsectp(capx[c], capy[c]);
1094 sct->sct_type = SCT_AIRPT;
1095 sct->sct_newtype = SCT_AIRPT;
1097 set_coastal_flags();
1100 /****************************************************************************
1101 PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1102 ****************************************************************************/
1108 for (i = 0; i < WORLD_Y; ++i) {
1112 for (j = i % 2; j < WORLD_X; j += 2) {
1113 if (own[j][i] == -1)
1116 printf("%c ", map_symbol(j, i));
1122 printf("\n\nEach continent is marked by a \"*\" on the map (to distinguish them from\n"
1123 "the islands). You can redesignate these airfields to wilderness sectors\n"
1124 "one at a time, each time you add a new country to the game.\n");
1128 map_symbol(int x, int y)
1132 for (c = 0; c < nc; ++c)
1133 if ((x == capx[c] && y == capy[c])
1134 || (x == new_x(capx[c] + 2) && y == capy[c]))
1136 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
1137 || elev[x][y] >= HIGHMIN)
1139 return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
1142 /***************************************************************************
1143 WRITE A SCRIPT FOR PLACING CAPITALS
1144 ****************************************************************************/
1146 write_newcap_script(void)
1149 FILE *script = fopen(outfile, "w");
1152 printf("fairland: error, unable to write to %s.\n", outfile);
1156 for (c = 0; c < nc; ++c) {
1157 fprintf(script, "add %d %d %d p\n", c + 1, c + 1, c + 1);
1159 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1160 fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1162 fprintf(script, "add %d visitor visitor v\n", c + 1);
1168 qprint(const char *const fmt, ...)
1174 vfprintf(stdout, fmt, ap);
1180 set_coastal_flags(void)
1185 qprint("setting coastal flags...\n");
1186 for (i = 0; i < nc; ++i) {
1187 for (j = 0; j < sc; j++) {
1188 sp = getsectp(sectx[i][j], secty[i][j]);
1189 sp->sct_coastal = sectc[i][j];
1192 for (i = nc; i < nc + ni; ++i) {
1193 for (j = 0; j < isecs[i]; j++) {
1194 sp = getsectp(sectx[i][j], secty[i][j]);
1195 sp->sct_coastal = sectc[i][j];