2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2005, 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 the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23 * related information and legal notices. It is expected that any future
24 * projects/authors will amend these files as needed.
28 * fairland.c: Create a nice, new world
30 * Known contributors to this file:
35 /* define ORE 1 to add resources, define ORE 0 if you want to use another
36 program to add the resources */
40 /* If you don't specify these command line arguments, then these are the
42 #define DEFAULT_SPIKE 10
43 #define DEFAULT_MOUNTAIN 0
44 #define DEFAULT_CONTDIST 2
45 #define DEFAULT_ISLDIST 1
47 /* The following five numbers refer to elevation under which (in the case of
48 fertility or oil) or over which (in the case of iron, gold, and uranium)
49 sectors with that elevation will contain that resource. Elevation ranges
52 /* raise FERT_MAX for more fertility */
55 /* raise OIL_MAX for more oil */
58 /* lower IRON_MIN for more iron */
61 /* lower GOLD_MIN for more gold */
64 /* lower URAN_MIN for more uranium */
68 #include "../lib/gen/getopt.h"
84 #include "prototypes.h"
86 /* do not change these 4 defines */
87 #define LANDMIN 1 /* plate altitude for normal land */
88 #define HILLMIN 34 /* plate altitude for hills */
89 #define PLATMIN 36 /* plate altitude for plateau */
90 #define HIGHMIN 98 /* plate altitude for mountains */
92 static void qprint(const char * const fmt, ...)
93 ATTRIBUTE((format (printf, 1, 2)));
95 #define DEFAULT_OUTFILE_NAME "newcap_script"
96 static const char *outfile = DEFAULT_OUTFILE_NAME;
97 /* mark the continents with a * so you can tell them
98 from the islands 1 = mark, 0 = don't mark. */
99 static int AIRPORT_MARKER = 0;
101 /* don't let the islands crash into each other.
102 1 = don't merge, 0 = merge. */
103 static int DISTINCT_ISLANDS = 1;
105 #define XSIZE ((WORLD_X) / 2) /* basically world x-y size */
106 #define YSIZE (WORLD_Y)
107 #define STABLE_CYCLE 4 /* stability required for perterbed capitals */
108 #define INFINITY 999 /* a number which means "BIG" */
110 /* these defines prevent infinite loops:
113 #define COAST_SEARCH_MAX 200 /* how many times do we look for a coast sector
114 when growing continents and islands */
115 #define DRIFT_BEFORE_CHECK ((WORLD_X + WORLD_Y)/2)
116 #define DRIFT_MAX ((WORLD_X + WORLD_Y)*2)
117 #define MOUNTAIN_SEARCH_MAX 1000 /* how long do we try to place mountains */
122 #define new_x(newx) (((newx) + WORLD_X) % WORLD_X)
123 #define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y)
125 #define max(a,b) (a>b?a:b)
127 #define rnd(x) (random() % (x))
129 int secs; /* number of sectors grown */
130 int ctot; /* total number of continents and islands grown */
131 int *isecs; /* array of how large each island is */
133 int nc, sc, di, sp, pm, ni, is, id; /* the 8 arguments to this program */
134 unsigned long rnd_seed; /* optional seed can be passed as an argument */
135 int *capx, *capy; /* location of the nc capitals */
136 int *mc, mcc; /* array and counter used for stability
137 check when perturbing */
138 int spike; /* are we spiking? */
139 int mind; /* the final distance between capitals that
141 int dirx[] = { -2, -1, 1, 2, 1, -1 }; /* gyujnb */
142 int diry[] = { 0, -1, -1, 0, 1, 1 };
144 int **own; /* owner of the sector. -1 means water */
145 int **elev; /* elevation of the sectors */
146 int **sectx, **secty; /* the sectors for each continent */
147 int **sectc; /* which sectors are on the coast? */
148 int *vector; /* used for measuring distances */
149 int *weight; /* used for placing mountains */
150 int *dsea, *dmoun; /* the dist to the ocean and mountain */
151 FILE *sect_fptr; /* the file we write everything to */
152 struct sctstr **sects;
153 struct sctstr *sectsbuf;
154 int fl_status; /* is anything wrong? */
155 #define STATUS_NO_ROOM (1) /* there was no room to grow */
156 #define NUMTRIES 10 /* keep trying to grow this many times */
158 const char *numletter =
159 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
161 static void parse_args(int argc, char *argv[]);
162 static int allocate_memory(void);
163 static void init(void);
164 static int drift(void);
165 static void grow_continents(void);
166 static void create_elevations(void);
167 static void write_sects(void);
168 static int write_file(void);
169 static void output(void);
170 static int write_newcap_script(void);
171 static int stable(void);
172 static void elevate_land(void);
173 static void elevate_sea(void);
174 static void translate_continents(void);
175 static int map_symbol(int x, int y);
176 static void fl_sct_init(coord x, coord y, s_char *ptr);
178 static void print_vars(void);
179 static void fl_move(int);
180 static void next_coast(int c, int x, int y, int *xp, int *yp);
181 static void grow_islands(void);
183 /****************************************************************************
185 ****************************************************************************/
188 main(int argc, char *argv[])
191 char *config_file = NULL;
194 rnd_seed = time(NULL);
196 while ((opt = getopt(argc, argv, "ae:ioqs:R:")) != EOF) {
202 DISTINCT_ISLANDS = 0;
205 config_file = optarg;
217 rnd_seed = strtoul(optarg, NULL, 10);
222 if (emp_config(config_file))
225 parse_args(argc - optind, argv + optind);
226 if (allocate_memory() == -1)
233 qprint("\ntry #%d (out of %d)...", i + 1, NUMTRIES);
234 qprint("\n\n #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
235 qprint("seed is %lu\n", rnd_seed);
236 qprint("placing capitals...\n");
238 qprint("fairland: unstable drift -- try increasisg DRIFT_MAX\n");
239 qprint("growing continents...\n");
241 } while (fl_status && ++i < NUMTRIES);
243 fputs("ERROR: World not large enough to hold continents\n",
247 qprint("growing islands:");
249 qprint("\nelevating land...\n");
251 qprint("designating sectors...\n");
253 qprint("adding resources...\n");
255 qprint("writing to sectors file...\n");
256 if (write_file() == -1)
259 write_newcap_script();
261 qprint("\t*** Resources have not been added ***\n");
270 puts("Creating a planet with:\n");
271 printf("%d continents\n", nc);
272 printf("continent size: %d\n", sc);
273 printf("number of islands: %d\n", ni);
274 printf("average size of islands: %d\n", is);
275 printf("spike: %d%%\n", sp);
276 printf("%d%% of land is mountain (each continent will have %d mountains)\n",
277 pm, (pm * sc) / 100);
278 printf("minimum distance between continents: %d\n", di);
279 printf("minimum distance from islands to continents: %d\n", id);
280 printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
288 for (i = 1; i * i < n * 10000; ++i) ;
289 return (i + 50) / 100;
292 /****************************************************************************
293 PARSE COMMAND LINE ARGUMENTS
294 ****************************************************************************/
297 parse_args(int argc, char *argv[])
299 if (argc < 2 || argc > 8) {
300 puts("fairland syntax:\n");
301 puts("fairland [-e config] [-aiqo] [-s script] [-R seed] <nc> <sc> [<ni>] [<is>] [<sp>] [<pm>] [<di>] [<id>]");
302 puts("-q = quiet, -o = no ore produced");
303 puts("-a = Airport marker for continents, -i = islands not distinct");
304 puts("-R = seed to use for random, -e = read config file");
305 printf("-s = name of script (default = %s)\n",
306 DEFAULT_OUTFILE_NAME);
307 puts("nc = number of continents [MANDATORY]");
308 puts("sc = continent size [MANDATORY]");
309 puts("ni = number of islands (default = nc)");
310 puts("is = average size of islands (default = sc/2)");
311 printf("sp = spike percentage: 0 = round, 100 = snake (default = %d)\n",
313 printf("pm = the percentage of land that is mountain (default = %d)\n",
315 printf("di = the minimum distance between continents (default = %d)\n",
317 printf("id = minimum distance from islands to continents (default = %d)\n",
323 puts("fairland: error -- number of continents must be > 0");
329 puts("fairland: error -- size of continents must be > 0");
357 pm = DEFAULT_MOUNTAIN;
364 di = DEFAULT_CONTDIST;
367 puts("fairland: error -- distance between continents must be >= 0");
370 if (di > WORLD_X / 2 || di > WORLD_Y / 2) {
371 puts("fairland: error -- distance between continents too large");
378 id = DEFAULT_ISLDIST;
380 puts("fairland: error -- distance from islands to continents must be >= 0");
383 if (id > WORLD_X || id > WORLD_Y) {
384 puts("fairland: error -- distance from islands to continents too large");
387 if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
388 puts("fairland: error -- world not big enough to fit continents.");
389 puts("arguments must satisfy:");
390 puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
395 /****************************************************************************
396 VARIABLE INITIALIZATION
397 ****************************************************************************/
400 allocate_memory(void)
405 fname = malloc(strlen(datadir) + 1 + strlen(empfile[EF_SECTOR].file) + 1);
406 sprintf(fname, "%s/%s", datadir, empfile[EF_SECTOR].file);
407 sect_fptr = fopen(fname, "wb");
408 if (sect_fptr == NULL) {
414 (struct sctstr *)calloc((YSIZE * XSIZE), sizeof(struct sctstr));
415 sects = (struct sctstr **)calloc(YSIZE, sizeof(struct sctstr *));
416 for (i = 0; i < YSIZE; i++)
417 sects[i] = §sbuf[XSIZE * i];
418 capx = (int *)calloc(nc, sizeof(int));
419 capy = (int *)calloc(nc, sizeof(int));
420 vector = (int *)calloc(WORLD_X + WORLD_Y, sizeof(int));
421 mc = (int *)calloc(STABLE_CYCLE, sizeof(int));
422 own = (int **)calloc(WORLD_X, sizeof(int *));
423 elev = (int **)calloc(WORLD_X, sizeof(int *));
424 for (i = 0; i < WORLD_X; ++i) {
425 own[i] = (int *)calloc(WORLD_Y, sizeof(int));
426 elev[i] = (int *)calloc(WORLD_Y, sizeof(int));
428 sectx = (int **)calloc(nc + ni, sizeof(int *));
429 secty = (int **)calloc(nc + ni, sizeof(int *));
430 sectc = (int **)calloc(nc + ni, sizeof(int *));
431 isecs = (int *)calloc(nc + ni, sizeof(int));
432 weight = (int *)calloc(max(sc, is * 2), sizeof(int));
433 dsea = (int *)calloc(max(sc, is * 2), sizeof(int));
434 dmoun = (int *)calloc(max(sc, is * 2), sizeof(int));
435 for (i = 0; i < nc; ++i) {
436 sectx[i] = (int *)calloc(sc, sizeof(int));
437 secty[i] = (int *)calloc(sc, sizeof(int));
438 sectc[i] = (int *)calloc(sc, sizeof(int));
440 for (i = nc; i < nc + ni; ++i) {
441 sectx[i] = (int *)calloc(is * 2, sizeof(int));
442 secty[i] = (int *)calloc(is * 2, sizeof(int));
443 sectc[i] = (int *)calloc(is * 2, sizeof(int));
452 int i, j, xx = 0, yy = 0;
457 for (i = 0; i < WORLD_X; ++i) {
458 for (j = 0; j < WORLD_Y; ++j) {
460 elev[i][j] = -INFINITY;
464 for (i = 0; i < nc; ++i, xx += 2) {
469 puts("fairland error: world not big enough for all the continents.\n");
476 for (i = 0; i < STABLE_CYCLE; ++i)
480 /****************************************************************************
481 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
482 ****************************************************************************/
484 /* How isolated is capital j?
487 iso(int j, int newx, int newy)
489 int i, md, d = WORLD_X + WORLD_Y;
491 for (i = 0; i < nc; ++i) {
494 md = mapdist(capx[i], capy[i], newx, newy);
502 /* Drift all the capitals
509 for (turns = 0; turns < DRIFT_MAX; ++turns) {
510 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
512 for (i = 0; i < nc; ++i)
518 /* Check to see if we have stabilized--can we stop drifting the capitals?
524 int i, isod, d = 0, stab = 1;
526 for (i = 0; i < nc; ++i) {
527 isod = iso(i, capx[i], capy[i]);
531 for (i = 0; i < STABLE_CYCLE; ++i)
535 mcc = (mcc + 1) % STABLE_CYCLE;
539 /* This routine does the actual drifting
545 int i, n, newx, newy;
547 for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
548 newx = new_x(capx[j] + dirx[i]);
549 newy = new_y(capy[j] + diry[i]);
550 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
558 /****************************************************************************
560 ****************************************************************************/
562 /* Look for a coastal sector of continent c
570 for (i = 0; i < secs; ++i) {
572 for (j = 0; j < 6; ++j)
573 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
578 /* Used for measuring distances
590 for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
593 return i > 1 || vector[0] > 0;
596 /* Test to see if we're allowed to grow there: the arguments di and id
599 try_to_grow(int c, int newx, int newy, int d)
603 for (i = 1; i <= d; ++i) {
604 for (j = 0; j < i; ++j)
609 for (j = 0; j < i; ++j) {
610 px = new_x(px + dirx[vector[j]]);
611 py = new_y(py + diry[vector[j]]);
613 if (own[px][py] != -1 &&
615 (DISTINCT_ISLANDS || own[px][py] < nc))
617 } while (next_vector(i));
619 sectx[c][secs] = newx;
620 secty[c][secs] = newy;
625 /* Move along the coast in a clockwise direction.
629 next_coast(int c, int x, int y, int *xp, int *yp)
631 int i, nx, ny, wat = 0;
639 for (i = 0; i < 12; ++i) {
640 nx = new_x(x + dirx[i % 6]);
641 ny = new_y(y + diry[i % 6]);
642 if (own[nx][ny] == -1)
644 if (wat && own[nx][ny] == c) {
652 /* Choose a sector to grow from
664 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
669 } while (i != starti);
671 printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n",
680 /* Grow continent c by 1 sector
684 grow_one_sector(int c)
686 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
688 spike = rnd(100) < sp;
689 if ((try1 = new_try(c)) == -1)
691 x = sx = sectx[c][try1];
692 y = sy = secty[c][try1];
697 for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
698 newx = new_x(x + dirx[i]);
699 newy = new_y(y + diry[i]);
700 if (own[newx][newy] == -1 &&
702 (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
703 own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
704 if (try_to_grow(c, newx, newy, c < nc ? di : id))
708 for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
709 newx = new_x(x + dirx[i]);
710 newy = new_y(y + diry[i]);
711 if (own[newx][newy] == -1)
712 if (try_to_grow(c, newx, newy, c < nc ? di : id))
715 next_coast(c, x, y, &x, &y);
717 } while (!done && coast_search < COAST_SEARCH_MAX &&
718 (secs == 1 || x != sx || y != sy));
719 if (!done && c < nc) {
720 qprint("fairland: error -- continent %c had no room to grow!\n",
722 fl_status |= STATUS_NO_ROOM;
727 /* Grow all the continents
730 grow_continents(void)
734 for (c = 0; c < nc; ++c) {
735 sectx[c][0] = capx[c];
736 secty[c][0] = capy[c];
737 own[sectx[c][0]][secty[c][0]] = c;
738 sectx[c][1] = new_x(capx[c] + 2);
739 secty[c][1] = capy[c];
740 own[sectx[c][1]][secty[c][1]] = c;
743 for (secs = 2; secs < sc && !fl_status; ++secs) {
744 for (c = 0; c < nc; ++c) {
750 qprint("Only managed to grow %d out of %d sectors.\n", secs, sc);
754 /****************************************************************************
756 ****************************************************************************/
758 /* Choose a place to start growing an island from
761 place_island(int c, int *xp, int *yp)
764 int ssy = rnd(WORLD_Y);
765 int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2);
767 if (ssx > WORLD_X - 2)
768 ssx = new_x(ssx + 2);
769 for (d = di + id; d >= id; --d) {
773 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
774 if (*xp >= WORLD_X) {
775 *yp = new_y(*yp + 1);
777 if (*xp == sx && *yp == sy)
780 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
787 /* Grow all the islands
795 for (c = nc; c < nc + ni; ++c) {
797 if (!place_island(c, &x, &y))
799 isiz = 1 + rnd(2 * is - 1);
803 } while (secs < isiz && grow_one_sector(c));
804 qprint(" %d(%d)", c - nc + 1, secs);
810 /****************************************************************************
812 ****************************************************************************/
814 create_elevations(void)
820 /* Generic function for finding the distance to the closest sea, land, or
824 distance_to_what(int x, int y, int flag)
828 for (d = 1; d < 5; ++d) {
829 for (j = 0; j < d; ++j)
834 for (j = 0; j < d; ++j) {
835 px = new_x(px + dirx[vector[j]]);
836 py = new_y(py + diry[vector[j]]);
839 case 0: /* distance to sea */
840 if (own[px][py] == -1)
843 case 1: /* distance to land */
844 if (own[px][py] != -1)
847 case 2: /* distance to mountain */
848 if (elev[px][py] == INFINITY)
852 } while (next_vector(d));
857 #define ELEV elev[sectx[c][i]][secty[c][i]]
858 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
859 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
861 /* Decide where the mountains go
866 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
869 for (c = 0; c < ctot; ++c) {
871 ns = (c < nc) ? sc : isecs[c];
872 nm = (pm * ns) / 100;
874 /* Place the mountains */
876 for (i = 0; i < ns; ++i) {
877 dsea[i] = distance_to_sea();
878 weight[i] = (total += (dsea[i] * dsea[i]));
881 for (k = nm, mountain_search = 0;
882 k && mountain_search < MOUNTAIN_SEARCH_MAX;
885 for (i = 0; i < ns; ++i)
886 if (r < weight[i] && ELEV == -INFINITY &&
888 ((!(capx[c] == sectx[c][i] &&
889 capy[c] == secty[c][i])) &&
890 (!(new_x(capx[c] + 2) == sectx[c][i] &&
891 capy[c] == secty[c][i]))))) {
898 /* Elevate land that is not mountain and not capital */
900 for (i = 0; i < ns; ++i)
901 dmoun[i] = distance_to_mountain();
902 dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
903 (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
905 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
908 for (i = 0; i < ns; ++i) {
909 if (ELEV != INFINITY &&
910 (c >= nc || ((!(capx[c] == sectx[c][i] &&
911 capy[c] == secty[c][i])) &&
912 (!(new_x(capx[c] + 2) == sectx[c][i] &&
913 capy[c] == secty[c][i]))))) {
914 h = 3 * (5 - dmoun[i]) + dsea[i];
924 if (newk >= HILLMIN && newk < PLATMIN)
928 elev[sectx[c][where]][secty[c][where]] = newk;
929 dsea[where] = -INFINITY;
930 dmoun[where] = INFINITY;
933 /* Elevate the mountains and capitals */
935 for (i = 0; i < ns; ++i) {
936 if (ELEV == INFINITY) {
938 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
940 ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) +
941 rnd((256 - HIGHMIN) / 2);
942 } else if ((c < nc &&
943 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
944 ((new_x(capx[c] + 2) == sectx[c][i] &&
945 capy[c] == secty[c][i])))
951 #define distance_to_land() distance_to_what(x, y, 1)
958 for (y = 0; y < WORLD_Y; ++y) {
959 for (x = y % 2; x < WORLD_X; x += 2) {
960 if (elev[x][y] == -INFINITY)
961 elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
966 /****************************************************************************
968 ****************************************************************************/
975 fert = LANDMIN - e + 40;
976 else if (e < FERT_MAX)
977 fert = (140 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
988 oil = (LANDMIN - e) * 2 + rnd(2);
989 else if (e <= OIL_MAX)
990 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1000 if (e >= IRON_MIN && e < HIGHMIN)
1001 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1011 if (e >= GOLD_MIN) {
1013 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1015 gold = 100 - 20 * HIGHMIN / e;
1026 if (e >= URAN_MIN && e < HIGHMIN)
1027 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1034 add_resources(struct sctstr *sct)
1036 sct->sct_fertil = set_fert(sct->sct_elev);
1037 sct->sct_oil = set_oil(sct->sct_elev);
1038 sct->sct_min = set_iron(sct->sct_elev);
1039 sct->sct_gmin = set_gold(sct->sct_elev);
1040 sct->sct_uran = set_uran(sct->sct_elev);
1043 /****************************************************************************
1044 DESIGNATE THE SECTORS
1045 ****************************************************************************/
1053 /* sct = §s[0][0]; */
1055 for (y = 0; y < YSIZE; y++) {
1056 for (x = 0; x < XSIZE; x++, sct++) {
1057 fl_sct_init(x * 2 + (y & 01), y, (s_char *)sct);
1058 total = elev[sct->sct_x][y];
1059 if (total < LANDMIN) {
1060 sct->sct_type = SCT_WATER;
1061 } else if (total < HILLMIN)
1062 sct->sct_type = SCT_RURAL;
1063 else if (total < PLATMIN)
1064 sct->sct_type = SCT_MOUNT;
1065 else if (total < HIGHMIN)
1066 sct->sct_type = SCT_RURAL;
1068 sct->sct_type = SCT_MOUNT;
1069 sct->sct_elev = total;
1070 sct->sct_newtype = sct->sct_type;
1076 for (c = 0; c < nc; ++c) {
1077 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_type = SCT_AIRPT;
1078 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_newtype = SCT_AIRPT;
1082 /****************************************************************************
1083 WRITE ALL THIS STUFF TO THE FILE
1084 ****************************************************************************/
1090 if ((n = fwrite((void *)sectsbuf, sizeof(struct sctstr),
1091 YSIZE * XSIZE, sect_fptr)) <= 0) {
1092 perror(empfile[EF_SECTOR].file);
1095 if (n != YSIZE * XSIZE) {
1096 printf("%s:partial write\n", empfile[EF_SECTOR].file);
1103 /****************************************************************************
1104 PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1105 ****************************************************************************/
1111 translate_continents();
1113 for (i = 0; i < WORLD_Y; ++i) {
1117 for (j = i % 2; j < WORLD_X; j += 2) {
1118 if (own[j][i] == -1)
1121 printf("%c ", map_symbol(j, i));
1127 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");
1130 /* Reorder the continents from top left to bottom right */
1132 translate_continents(void)
1134 int i, j, n = 0, k, gotit, c;
1135 int *trans, *trans_cont, *oldcapx, *oldcapy;
1137 trans = (int *)calloc(nc, sizeof(int));
1138 trans_cont = (int *)calloc(nc, sizeof(int));
1139 oldcapx = (int *)calloc(nc, sizeof(int));
1140 oldcapy = (int *)calloc(nc, sizeof(int));
1142 for (i = 0; i < WORLD_Y; ++i) {
1143 for (j = i % 2; j < WORLD_X; j += 2) {
1144 if (own[j][i] > -1 && own[j][i] < nc) {
1146 for (k = 0; k < n; ++k) {
1147 if (trans[k] == own[j][i])
1152 printf("fairland: BUG in translate continents! mail stevens@math.utoronto.ca\n");
1155 trans[n] = own[j][i];
1156 trans_cont[own[j][i]] = n;
1162 for (i = 0; i < WORLD_Y; ++i) {
1163 for (j = i % 2; j < WORLD_X; j += 2) {
1164 if (own[j][i] > -1 && own[j][i] < nc) {
1165 own[j][i] = trans_cont[own[j][i]];
1169 for (c = 0; c < nc; ++c) {
1170 oldcapx[c] = capx[c];
1171 oldcapy[c] = capy[c];
1173 for (c = 0; c < nc; ++c) {
1174 capx[c] = oldcapx[trans[c]];
1175 capy[c] = oldcapy[trans[c]];
1180 map_symbol(int x, int y)
1184 for (c = 0; c < nc; ++c)
1185 if ((x == capx[c] && y == capy[c])
1186 || (x == new_x(capx[c] + 2) && y == capy[c]))
1188 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
1189 || elev[x][y] >= HIGHMIN)
1191 return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
1194 /***************************************************************************
1195 WRITE A SCRIPT FOR PLACING CAPITALS
1196 ****************************************************************************/
1198 write_newcap_script(void)
1201 FILE *script = fopen(outfile, "w");
1204 printf("fairland: error, unable to write to %s.\n", outfile);
1208 for (c = 0; c < nc; ++c) {
1209 fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1);
1211 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1212 fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1214 fprintf(script, "add %d visitor visitor v i\n", c + 1);
1217 qprint("\n\nA script for adding all the countries can be found in \"%s\".\n",
1223 qprint(const char * const fmt, ...)
1229 vfprintf(stdout, fmt, ap);
1235 fl_sct_init(coord x, coord y, s_char *ptr)
1237 struct sctstr *sp = (struct sctstr *)ptr;
1239 sp->ef_type = EF_SECTOR;
1246 sp->sct_defense = 0;