2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
4 * Ken Stevens, Steve McClure
6 * This program 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 2 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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * See files README, COPYING and CREDITS in the root of the source
23 * tree for related information and legal notices. It is expected
24 * that future projects/authors will amend these files as needed.
28 * fairland.c: Create a nice, new world
30 * Known contributors to this file:
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 */
78 #include "prototypes.h"
83 /* do not change these 4 defines */
84 #define LANDMIN 1 /* plate altitude for normal land */
85 #define HILLMIN 34 /* plate altitude for hills */
86 #define PLATMIN 36 /* plate altitude for plateau */
87 #define HIGHMIN 98 /* plate altitude for mountains */
89 static void qprint(const char * const fmt, ...)
90 ATTRIBUTE((format (printf, 1, 2)));
92 #define DEFAULT_OUTFILE_NAME "newcap_script"
93 static const char *outfile = DEFAULT_OUTFILE_NAME;
94 /* mark the continents with a * so you can tell them
95 from the islands 1 = mark, 0 = don't mark. */
96 static int AIRPORT_MARKER = 0;
98 /* don't let the islands crash into each other.
99 1 = don't merge, 0 = merge. */
100 static int DISTINCT_ISLANDS = 1;
102 static char *program_name;
104 #define STABLE_CYCLE 4 /* stability required for perterbed capitals */
105 #define INFINITY 999 /* a number which means "BIG" */
107 /* these defines prevent infinite loops:
110 #define COAST_SEARCH_MAX 200 /* how many times do we look for a coast sector
111 when growing continents and islands */
112 #define DRIFT_BEFORE_CHECK ((WORLD_X + WORLD_Y)/2)
113 #define DRIFT_MAX ((WORLD_X + WORLD_Y)*2)
114 #define MOUNTAIN_SEARCH_MAX 1000 /* how long do we try to place mountains */
119 #define new_x(newx) (((newx) + WORLD_X) % WORLD_X)
120 #define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y)
121 #define rnd(x) (random() % (x))
123 int secs; /* number of sectors grown */
124 int ctot; /* total number of continents and islands grown */
125 int *isecs; /* array of how large each island is */
127 int nc, sc, di, sp, pm, ni, is, id; /* the 8 arguments to this program */
128 unsigned long rnd_seed; /* optional seed can be passed as an argument */
129 int *capx, *capy; /* location of the nc capitals */
130 int *mc, mcc; /* array and counter used for stability
131 check when perturbing */
132 int spike; /* are we spiking? */
133 int mind; /* the final distance between capitals that
135 int dirx[] = { -2, -1, 1, 2, 1, -1 }; /* gyujnb */
136 int diry[] = { 0, -1, -1, 0, 1, 1 };
138 int **own; /* owner of the sector. -1 means water */
139 int **elev; /* elevation of the sectors */
140 int **sectx, **secty; /* the sectors for each continent */
141 int **sectc; /* which sectors are on the coast? */
142 int *vector; /* used for measuring distances */
143 int *weight; /* used for placing mountains */
144 int *dsea, *dmoun; /* the dist to the ocean and mountain */
145 int fl_status; /* is anything wrong? */
146 #define STATUS_NO_ROOM 1 /* there was no room to grow */
147 #define NUMTRIES 10 /* keep trying to grow this many times */
149 const char *numletter =
150 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
152 static void help(char *);
153 static void usage(void);
154 static void parse_args(int argc, char *argv[]);
155 static int allocate_memory(void);
156 static void init(void);
157 static int drift(void);
158 static void grow_continents(void);
159 static void create_elevations(void);
160 static void write_sects(void);
161 static void output(void);
162 static int write_newcap_script(void);
163 static int stable(void);
164 static void elevate_land(void);
165 static void elevate_sea(void);
166 static int map_symbol(int x, int y);
167 static void set_coastal_flags(void);
169 static void print_vars(void);
170 static void fl_move(int);
171 static void next_coast(int c, int x, int y, int *xp, int *yp);
172 static void grow_islands(void);
174 /****************************************************************************
176 ****************************************************************************/
179 main(int argc, char *argv[])
182 char *config_file = NULL;
185 program_name = argv[0];
186 rnd_seed = time(NULL);
188 while ((opt = getopt(argc, argv, "ae:hioqR:s:v")) != EOF) {
194 config_file = optarg;
197 DISTINCT_ISLANDS = 0;
206 rnd_seed = strtoul(optarg, NULL, 10);
215 printf("%s\n\n%s", version, legal);
222 parse_args(argc - optind, argv + optind);
226 if (emp_config(config_file) < 0)
230 if (allocate_memory() == -1)
237 qprint("\ntry #%d (out of %d)...", i + 1, NUMTRIES);
238 qprint("\n\n #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
239 qprint("seed is %lu\n", rnd_seed);
240 qprint("placing capitals...\n");
242 qprint("fairland: unstable drift -- try increasisg DRIFT_MAX\n");
243 qprint("growing continents...\n");
245 } while (fl_status && ++i < NUMTRIES);
247 fputs("ERROR: World not large enough to hold continents\n",
251 qprint("growing islands:");
253 qprint("\nelevating land...\n");
255 qprint("designating sectors...\n");
257 qprint("adding resources...\n");
258 write_newcap_script();
260 if (chdir(gamedir)) {
261 fprintf(stderr, "Can't chdir to %s (%s)\n", gamedir, strerror(errno));
264 if (!ef_open(EF_SECTOR, EFF_MEM | EFF_NOTIME, WORLD_SZ())) {
269 qprint("writing to sectors file...\n");
270 if (!ef_close(EF_SECTOR))
274 qprint("\n\nA script for adding all the countries can be found in \"%s\".\n",
277 qprint("\t*** Resources have not been added ***\n");
286 puts("Creating a planet with:\n");
287 printf("%d continents\n", nc);
288 printf("continent size: %d\n", sc);
289 printf("number of islands: %d\n", ni);
290 printf("average size of islands: %d\n", is);
291 printf("spike: %d%%\n", sp);
292 printf("%d%% of land is mountain (each continent will have %d mountains)\n",
293 pm, (pm * sc) / 100);
294 printf("minimum distance between continents: %d\n", di);
295 printf("minimum distance from islands to continents: %d\n", id);
296 printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
304 for (i = 1; i * i < n * 10000; ++i) ;
305 return (i + 50) / 100;
308 /****************************************************************************
309 PARSE COMMAND LINE ARGUMENTS
310 ****************************************************************************/
313 help(char *complaint)
316 fprintf(stderr, "%s: %s\n", program_name, complaint);
317 fprintf(stderr, "Try -h for help.\n");
323 printf("Usage: %s [OPTION]... NC SC [NI] [IS] [SP] [PM] [DI] [ID]\n"
324 " -a airport marker for continents\n"
325 " -e CONFIG-FILE configuration file\n"
327 " -h display this help and exit\n"
328 " -i islands may merge\n"
329 " -o don't set resources\n"
331 " -R SEED seed for random number generator\n"
332 " -s SCRIPT name of script to create (default %s)\n"
333 " NC number of continents\n"
334 " SC continent size\n"
335 " NI number of islands (default NC)\n"
336 " IS average island size (default SC/2)\n"
337 " SP spike percentage: 0 = round, 100 = snake (default %d)\n"
338 " PM percentage of land that is mountain (default %d)\n"
339 " DI minimum distance between continents (default %d)\n"
340 " ID minimum distance from islands to continents (default %d)\n",
341 program_name, dflt_econfig, DEFAULT_OUTFILE_NAME,
342 DEFAULT_SPIKE, DEFAULT_MOUNTAIN, DEFAULT_CONTDIST, DEFAULT_ISLDIST);
346 parse_args(int argc, char *argv[])
349 help("missing arguments");
353 help("too many arguments");
358 puts("fairland: error -- number of continents must be > 0");
364 puts("fairland: error -- size of continents must be > 0");
392 pm = DEFAULT_MOUNTAIN;
399 di = DEFAULT_CONTDIST;
402 puts("fairland: error -- distance between continents must be >= 0");
405 if (di > WORLD_X / 2 || di > WORLD_Y / 2) {
406 puts("fairland: error -- distance between continents too large");
413 id = DEFAULT_ISLDIST;
415 puts("fairland: error -- distance from islands to continents must be >= 0");
418 if (id > WORLD_X || id > WORLD_Y) {
419 puts("fairland: error -- distance from islands to continents too large");
422 if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
423 puts("fairland: error -- world not big enough to fit continents.");
424 puts("arguments must satisfy:");
425 puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
430 /****************************************************************************
431 VARIABLE INITIALIZATION
432 ****************************************************************************/
435 allocate_memory(void)
439 capx = calloc(nc, sizeof(int));
440 capy = calloc(nc, sizeof(int));
441 vector = calloc(WORLD_X + WORLD_Y, sizeof(int));
442 mc = calloc(STABLE_CYCLE, sizeof(int));
443 own = calloc(WORLD_X, sizeof(int *));
444 elev = calloc(WORLD_X, sizeof(int *));
445 for (i = 0; i < WORLD_X; ++i) {
446 own[i] = calloc(WORLD_Y, sizeof(int));
447 elev[i] = calloc(WORLD_Y, sizeof(int));
449 sectx = calloc(nc + ni, sizeof(int *));
450 secty = calloc(nc + ni, sizeof(int *));
451 sectc = calloc(nc + ni, sizeof(int *));
452 isecs = calloc(nc + ni, sizeof(int));
453 weight = calloc(MAX(sc, is * 2), sizeof(int));
454 dsea = calloc(MAX(sc, is * 2), sizeof(int));
455 dmoun = calloc(MAX(sc, is * 2), sizeof(int));
456 for (i = 0; i < nc; ++i) {
457 sectx[i] = calloc(sc, sizeof(int));
458 secty[i] = calloc(sc, sizeof(int));
459 sectc[i] = calloc(sc, sizeof(int));
461 for (i = nc; i < nc + ni; ++i) {
462 sectx[i] = calloc(is * 2, sizeof(int));
463 secty[i] = calloc(is * 2, sizeof(int));
464 sectc[i] = calloc(is * 2, sizeof(int));
473 int i, j, xx = 0, yy = 0;
478 for (i = 0; i < WORLD_X; ++i) {
479 for (j = 0; j < WORLD_Y; ++j) {
481 elev[i][j] = -INFINITY;
485 for (i = 0; i < nc; ++i) {
490 puts("fairland error: world not big enough for all the continents.\n");
498 for (i = 0; i < STABLE_CYCLE; ++i)
502 /****************************************************************************
503 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
504 ****************************************************************************/
506 /* How isolated is capital j?
509 iso(int j, int newx, int newy)
511 int i, md, d = WORLD_X + WORLD_Y;
513 for (i = 0; i < nc; ++i) {
516 md = mapdist(capx[i], capy[i], newx, newy);
524 /* Drift all the capitals
531 for (turns = 0; turns < DRIFT_MAX; ++turns) {
532 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
534 for (i = 0; i < nc; ++i)
540 /* Check to see if we have stabilized--can we stop drifting the capitals?
546 int i, isod, d = 0, stab = 1;
548 for (i = 0; i < nc; ++i) {
549 isod = iso(i, capx[i], capy[i]);
553 for (i = 0; i < STABLE_CYCLE; ++i)
557 mcc = (mcc + 1) % STABLE_CYCLE;
561 /* This routine does the actual drifting
567 int i, n, newx, newy;
569 for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
570 newx = new_x(capx[j] + dirx[i]);
571 newy = new_y(capy[j] + diry[i]);
572 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
580 /****************************************************************************
582 ****************************************************************************/
584 /* Look for a coastal sector of continent c
592 for (i = 0; i < secs; ++i) {
594 for (j = 0; j < 6; ++j)
595 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
600 /* Used for measuring distances
612 for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
615 return i > 1 || vector[0] > 0;
618 /* Test to see if we're allowed to grow there: the arguments di and id
621 try_to_grow(int c, int newx, int newy, int d)
625 for (i = 1; i <= d; ++i) {
626 for (j = 0; j < i; ++j)
631 for (j = 0; j < i; ++j) {
632 px = new_x(px + dirx[vector[j]]);
633 py = new_y(py + diry[vector[j]]);
635 if (own[px][py] != -1 &&
637 (DISTINCT_ISLANDS || own[px][py] < nc))
639 } while (next_vector(i));
641 sectx[c][secs] = newx;
642 secty[c][secs] = newy;
647 /* Move along the coast in a clockwise direction.
651 next_coast(int c, int x, int y, int *xp, int *yp)
653 int i, nx, ny, wat = 0;
661 for (i = 0; i < 12; ++i) {
662 nx = new_x(x + dirx[i % 6]);
663 ny = new_y(y + diry[i % 6]);
664 if (own[nx][ny] == -1)
666 if (wat && own[nx][ny] == c) {
674 /* Choose a sector to grow from
686 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
691 } while (i != starti);
693 printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n",
702 /* Grow continent c by 1 sector
706 grow_one_sector(int c)
708 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
710 spike = rnd(100) < sp;
711 if ((try1 = new_try(c)) == -1)
713 x = sx = sectx[c][try1];
714 y = sy = secty[c][try1];
719 for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
720 newx = new_x(x + dirx[i]);
721 newy = new_y(y + diry[i]);
722 if (own[newx][newy] == -1 &&
724 (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
725 own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
726 if (try_to_grow(c, newx, newy, c < nc ? di : id))
730 for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
731 newx = new_x(x + dirx[i]);
732 newy = new_y(y + diry[i]);
733 if (own[newx][newy] == -1)
734 if (try_to_grow(c, newx, newy, c < nc ? di : id))
737 next_coast(c, x, y, &x, &y);
739 } while (!done && coast_search < COAST_SEARCH_MAX &&
740 (secs == 1 || x != sx || y != sy));
741 if (!done && c < nc) {
742 qprint("fairland: error -- continent %c had no room to grow!\n",
744 fl_status |= STATUS_NO_ROOM;
749 /* Grow all the continents
752 grow_continents(void)
756 for (c = 0; c < nc; ++c) {
757 sectx[c][0] = capx[c];
758 secty[c][0] = capy[c];
759 own[sectx[c][0]][secty[c][0]] = c;
760 sectx[c][1] = new_x(capx[c] + 2);
761 secty[c][1] = capy[c];
762 own[sectx[c][1]][secty[c][1]] = c;
765 for (secs = 2; secs < sc && !fl_status; ++secs) {
766 for (c = 0; c < nc; ++c) {
771 for (c = 0; c < nc; ++c)
775 qprint("Only managed to grow %d out of %d sectors.\n", secs, sc);
779 /****************************************************************************
781 ****************************************************************************/
783 /* Choose a place to start growing an island from
786 place_island(int c, int *xp, int *yp)
789 int ssy = rnd(WORLD_Y);
790 int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2);
792 if (ssx > WORLD_X - 2)
793 ssx = new_x(ssx + 2);
794 for (d = di + id; d >= id; --d) {
798 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
799 if (*xp >= WORLD_X) {
800 *yp = new_y(*yp + 1);
802 if (*xp == sx && *yp == sy)
805 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
812 /* Grow all the islands
820 for (c = nc; c < nc + ni; ++c) {
822 if (!place_island(c, &x, &y))
824 isiz = 1 + rnd(2 * is - 1);
828 } while (secs < isiz && grow_one_sector(c));
830 qprint(" %d(%d)", c - nc + 1, secs);
836 /****************************************************************************
838 ****************************************************************************/
840 create_elevations(void)
846 /* Generic function for finding the distance to the closest sea, land, or
850 distance_to_what(int x, int y, int flag)
854 for (d = 1; d < 5; ++d) {
855 for (j = 0; j < d; ++j)
860 for (j = 0; j < d; ++j) {
861 px = new_x(px + dirx[vector[j]]);
862 py = new_y(py + diry[vector[j]]);
865 case 0: /* distance to sea */
866 if (own[px][py] == -1)
869 case 1: /* distance to land */
870 if (own[px][py] != -1)
873 case 2: /* distance to mountain */
874 if (elev[px][py] == INFINITY)
878 } while (next_vector(d));
883 #define ELEV elev[sectx[c][i]][secty[c][i]]
884 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
885 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
887 /* Decide where the mountains go
892 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
895 for (c = 0; c < ctot; ++c) {
897 ns = (c < nc) ? sc : isecs[c];
898 nm = (pm * ns) / 100;
900 /* Place the mountains */
902 for (i = 0; i < ns; ++i) {
903 dsea[i] = distance_to_sea();
904 weight[i] = (total += (dsea[i] * dsea[i]));
907 for (k = nm, mountain_search = 0;
908 k && mountain_search < MOUNTAIN_SEARCH_MAX;
911 for (i = 0; i < ns; ++i)
912 if (r < weight[i] && ELEV == -INFINITY &&
914 ((!(capx[c] == sectx[c][i] &&
915 capy[c] == secty[c][i])) &&
916 (!(new_x(capx[c] + 2) == sectx[c][i] &&
917 capy[c] == secty[c][i]))))) {
924 /* Elevate land that is not mountain and not capital */
926 for (i = 0; i < ns; ++i)
927 dmoun[i] = distance_to_mountain();
928 dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
929 (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
931 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
934 for (i = 0; i < ns; ++i) {
935 if (ELEV != INFINITY &&
936 (c >= nc || ((!(capx[c] == sectx[c][i] &&
937 capy[c] == secty[c][i])) &&
938 (!(new_x(capx[c] + 2) == sectx[c][i] &&
939 capy[c] == secty[c][i]))))) {
940 h = 3 * (5 - dmoun[i]) + dsea[i];
950 if (newk >= HILLMIN && newk < PLATMIN)
954 elev[sectx[c][where]][secty[c][where]] = newk;
955 dsea[where] = -INFINITY;
956 dmoun[where] = INFINITY;
959 /* Elevate the mountains and capitals */
961 for (i = 0; i < ns; ++i) {
962 if (ELEV == INFINITY) {
964 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
966 ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) +
967 rnd((256 - HIGHMIN) / 2);
968 } else if ((c < nc &&
969 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
970 ((new_x(capx[c] + 2) == sectx[c][i] &&
971 capy[c] == secty[c][i])))
977 #define distance_to_land() distance_to_what(x, y, 1)
984 for (y = 0; y < WORLD_Y; ++y) {
985 for (x = y % 2; x < WORLD_X; x += 2) {
986 if (elev[x][y] == -INFINITY)
987 elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
992 /****************************************************************************
994 ****************************************************************************/
1001 fert = LANDMIN - e + 40;
1002 else if (e < FERT_MAX)
1003 fert = (120 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
1014 oil = (LANDMIN - e) * 2 + rnd(2);
1015 else if (e <= OIL_MAX)
1016 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1026 if (e >= IRON_MIN && e < HIGHMIN)
1027 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1037 if (e >= GOLD_MIN) {
1039 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1041 gold = 100 - 20 * HIGHMIN / e;
1052 if (e >= URAN_MIN && e < HIGHMIN)
1053 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1060 add_resources(struct sctstr *sct)
1062 sct->sct_fertil = set_fert(sct->sct_elev);
1063 sct->sct_oil = set_oil(sct->sct_elev);
1064 sct->sct_min = set_iron(sct->sct_elev);
1065 sct->sct_gmin = set_gold(sct->sct_elev);
1066 sct->sct_uran = set_uran(sct->sct_elev);
1069 /****************************************************************************
1070 DESIGNATE THE SECTORS
1071 ****************************************************************************/
1079 for (y = 0; y < WORLD_Y; y++) {
1080 for (x = y % 2; x < WORLD_X; x += 2) {
1081 sct = getsectp(x, y);
1083 if (total < LANDMIN) {
1084 sct->sct_type = SCT_WATER;
1085 } else if (total < HILLMIN)
1086 sct->sct_type = SCT_RURAL;
1087 else if (total < PLATMIN)
1088 sct->sct_type = SCT_MOUNT;
1089 else if (total < HIGHMIN)
1090 sct->sct_type = SCT_RURAL;
1092 sct->sct_type = SCT_MOUNT;
1093 sct->sct_elev = total;
1094 sct->sct_newtype = sct->sct_type;
1100 for (c = 0; c < nc; ++c) {
1101 sct = getsectp(capx[c], capy[c]);
1102 sct->sct_type = SCT_AIRPT;
1103 sct->sct_newtype = SCT_AIRPT;
1105 set_coastal_flags();
1108 /****************************************************************************
1109 PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1110 ****************************************************************************/
1116 for (i = 0; i < WORLD_Y; ++i) {
1120 for (j = i % 2; j < WORLD_X; j += 2) {
1121 if (own[j][i] == -1)
1124 printf("%c ", map_symbol(j, i));
1130 printf("\n\nEach continent is marked by a \"*\" on the map (to distinguish them from\nthe islands). You can redesignate these airfields to wilderness sectors\none at a time, each time you add a new country to the game.\n");
1134 map_symbol(int x, int y)
1138 for (c = 0; c < nc; ++c)
1139 if ((x == capx[c] && y == capy[c])
1140 || (x == new_x(capx[c] + 2) && y == capy[c]))
1142 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
1143 || elev[x][y] >= HIGHMIN)
1145 return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
1148 /***************************************************************************
1149 WRITE A SCRIPT FOR PLACING CAPITALS
1150 ****************************************************************************/
1152 write_newcap_script(void)
1155 FILE *script = fopen(outfile, "w");
1158 printf("fairland: error, unable to write to %s.\n", outfile);
1162 for (c = 0; c < nc; ++c) {
1163 fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1);
1165 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1166 fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1168 fprintf(script, "add %d visitor visitor v i\n", c + 1);
1175 qprint(const char * const fmt, ...)
1181 vfprintf(stdout, fmt, ap);
1187 set_coastal_flags(void)
1192 qprint("setting coastal flags...\n");
1193 for (i = 0; i < nc; ++i) {
1194 for (j = 0; j < sc; j++) {
1195 sp = getsectp(sectx[i][j], secty[i][j]);
1196 sp->sct_coastal = sectc[i][j];
1199 for (i = nc; i < nc + ni; ++i) {
1200 for (j = 0; j < isecs[i]; j++) {
1201 sp = getsectp(sectx[i][j], secty[i][j]);
1202 sp->sct_coastal = sectc[i][j];