2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2004, 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 */
67 #if defined(aix) || defined(linux) || defined(solaris)
69 #endif /* aix or linux */
71 #include "../lib/gen/getopt.h"
86 #include "prototypes.h"
88 /* do not change these 4 defines */
89 #define LANDMIN 1 /* plate altitude for normal land */
90 #define HILLMIN 34 /* plate altitude for hills */
91 #define PLATMIN 36 /* plate altitude for plateau */
92 #define HIGHMIN 98 /* plate altitude for mountains */
94 static void qprint(const char * const fmt, ...)
95 ATTRIBUTE((format (printf, 1, 2)));
97 #define DEFAULT_OUTFILE_NAME "newcap_script"
98 static const char *outfile = DEFAULT_OUTFILE_NAME;
99 /* mark the continents with a * so you can tell them
100 from the islands 1 = mark, 0 = don't mark. */
101 static int AIRPORT_MARKER = 0;
103 /* don't let the islands crash into each other.
104 1 = don't merge, 0 = merge. */
105 static int DISTINCT_ISLANDS = 1;
107 #define XSIZE ((WORLD_X) / 2) /* basically world x-y size */
108 #define YSIZE (WORLD_Y)
109 #define STABLE_CYCLE 4 /* stability required for perterbed capitals */
110 #define INFINITY 999 /* a number which means "BIG" */
112 /* these defines prevent infinite loops:
115 #define COAST_SEARCH_MAX 200 /* how many times do we look for a coast sector
116 when growing continents and islands */
117 #define DRIFT_BEFORE_CHECK ((WORLD_X + WORLD_Y)/2)
118 #define DRIFT_MAX ((WORLD_X + WORLD_Y)*2)
119 #define MOUNTAIN_SEARCH_MAX 1000 /* how long do we try to place mountains */
124 #define new_x(newx) (((newx) + WORLD_X) % WORLD_X)
125 #define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y)
127 #define max(a,b) (a>b?a:b)
129 #define rnd(x) (random() % (x))
131 int secs; /* number of sectors grown */
132 int ctot; /* total number of continents and islands grown */
133 int *isecs; /* array of how large each island is */
135 int nc, sc, di, sp, pm, ni, is, id; /* the 8 arguments to this program */
136 unsigned long rnd_seed; /* optional seed can be passed as an argument */
137 int *capx, *capy; /* location of the nc capitals */
138 int *mc, mcc; /* array and counter used for stability
139 check when perturbing */
140 int spike; /* are we spiking? */
141 int mind; /* the final distance between capitals that
143 int dirx[] = { -2, -1, 1, 2, 1, -1 }; /* gyujnb */
144 int diry[] = { 0, -1, -1, 0, 1, 1 };
146 int **own; /* owner of the sector. -1 means water */
147 int **elev; /* elevation of the sectors */
148 int **sectx, **secty; /* the sectors for each continent */
149 int **sectc; /* which sectors are on the coast? */
150 int *vector; /* used for measuring distances */
151 int *weight; /* used for placing mountains */
152 int *dsea, *dmoun; /* the dist to the ocean and mountain */
153 int the_file; /* the file we write everything to */
154 struct sctstr **sects;
155 struct sctstr *sectsbuf;
156 int fl_status; /* is anything wrong? */
157 #define STATUS_NO_ROOM (1) /* there was no room to grow */
158 #define NUMTRIES 10 /* keep trying to grow this many times */
160 const char *numletter =
161 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
163 static void parse_args(int argc, char *argv[]);
164 static int allocate_memory(void);
165 static void init(void);
166 static int drift(void);
167 static void grow_continents(void);
168 static void create_elevations(void);
169 static void write_sects(void);
170 static int write_file(void);
171 static void output(void);
172 static int write_newcap_script(void);
173 static int stable(void);
174 static void elevate_land(void);
175 static void elevate_sea(void);
176 static void translate_continents(void);
177 static int map_symbol(int x, int y);
178 static void fl_sct_init(coord x, coord y, s_char *ptr);
180 static void print_vars(void);
181 static void fl_move(int);
182 static void next_coast(int c, int x, int y, int *xp, int *yp);
183 static void grow_islands(void);
185 /****************************************************************************
187 ****************************************************************************/
190 main(int argc, char *argv[])
193 char *config_file = NULL;
197 rnd_seed = time(NULL);
199 while ((opt = getopt(argc, argv, "ae:ioqs:R:")) != EOF) {
205 DISTINCT_ISLANDS = 0;
208 config_file = optarg;
220 rnd_seed = strtoul(optarg, NULL, 10);
225 if (config_file == NULL) {
226 sprintf(tbuf, "%s/econfig", datadir);
229 emp_config(config_file);
231 parse_args(argc - optind, argv + optind);
232 if (allocate_memory() == -1)
239 qprint("\ntry #%d (out of %d)...", i + 1, NUMTRIES);
240 qprint("\n\n #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
241 qprint("seed is %lu\n", rnd_seed);
242 qprint("placing capitals...\n");
244 qprint("fairland: unstable drift -- try increasisg DRIFT_MAX\n");
245 qprint("growing continents...\n");
247 } while (fl_status && ++i < NUMTRIES);
249 fputs("ERROR: World not large enough to hold continents\n",
253 qprint("growing islands:");
255 qprint("\nelevating land...\n");
257 qprint("designating sectors...\n");
259 qprint("adding resources...\n");
261 qprint("writing to sectors file...\n");
262 if (write_file() == -1)
265 write_newcap_script();
267 qprint("\t*** Resources have not been added ***\n");
276 puts("Creating a planet with:\n");
277 printf("%d continents\n", nc);
278 printf("continent size: %d\n", sc);
279 printf("number of islands: %d\n", ni);
280 printf("average size of islands: %d\n", is);
281 printf("spike: %d%%\n", sp);
282 printf("%d%% of land is mountain (each continent will have %d mountains)\n",
283 pm, (pm * sc) / 100);
284 printf("minimum distance between continents: %d\n", di);
285 printf("minimum distance from islands to continents: %d\n", id);
286 printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
294 for (i = 1; i * i < n * 10000; ++i) ;
295 return (i + 50) / 100;
298 /****************************************************************************
299 PARSE COMMAND LINE ARGUMENTS
300 ****************************************************************************/
303 parse_args(int argc, char *argv[])
305 if (argc < 2 || argc > 8) {
306 puts("fairland syntax:\n");
307 puts("fairland [-e config] [-aiqo] [-s script] [-R seed] <nc> <sc> [<ni>] [<is>] [<sp>] [<pm>] [<di>] [<id>]");
308 puts("-q = quiet, -o = no ore produced");
309 puts("-a = Airport marker for continents, -i = islands not distinct");
310 puts("-R = seed to use for random, -e = read config file");
311 printf("-s = name of script (default = %s)\n",
312 DEFAULT_OUTFILE_NAME);
313 puts("nc = number of continents [MANDATORY]");
314 puts("sc = continent size [MANDATORY]");
315 puts("ni = number of islands (default = nc)");
316 puts("is = average size of islands (default = sc/2)");
317 printf("sp = spike percentage: 0 = round, 100 = snake (default = %d)\n",
319 printf("pm = the percentage of land that is mountain (default = %d)\n",
321 printf("di = the minimum distance between continents (default = %d)\n",
323 printf("id = minimum distance from islands to continents (default = %d)\n",
329 puts("fairland: error -- number of continents must be > 0");
335 puts("fairland: error -- size of continents must be > 0");
363 pm = DEFAULT_MOUNTAIN;
370 di = DEFAULT_CONTDIST;
373 puts("fairland: error -- distance between continents must be >= 0");
376 if (di > WORLD_X / 2 || di > WORLD_Y / 2) {
377 puts("fairland: error -- distance between continents too large");
384 id = DEFAULT_ISLDIST;
386 puts("fairland: error -- distance from islands to continents must be >= 0");
389 if (id > WORLD_X || id > WORLD_Y) {
390 puts("fairland: error -- distance from islands to continents too large");
393 if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
394 puts("fairland: error -- world not big enough to fit continents.");
395 puts("arguments must satisfy:");
396 puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
401 /****************************************************************************
402 VARIABLE INITIALIZATION
403 ****************************************************************************/
406 allocate_memory(void)
412 open(empfile[EF_SECTOR].file, O_RDWR | O_CREAT | O_TRUNC, 0660);
415 open(empfile[EF_SECTOR].file,
416 O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0660);
419 perror(empfile[EF_SECTOR].file);
423 (struct sctstr *)calloc((YSIZE * XSIZE), sizeof(struct sctstr));
424 sects = (struct sctstr **)calloc(YSIZE, sizeof(struct sctstr *));
425 for (i = 0; i < YSIZE; i++)
426 sects[i] = §sbuf[XSIZE * i];
427 capx = (int *)calloc(nc, sizeof(int));
428 capy = (int *)calloc(nc, sizeof(int));
429 vector = (int *)calloc(WORLD_X + WORLD_Y, sizeof(int));
430 mc = (int *)calloc(STABLE_CYCLE, sizeof(int));
431 own = (int **)calloc(WORLD_X, sizeof(int *));
432 elev = (int **)calloc(WORLD_X, sizeof(int *));
433 for (i = 0; i < WORLD_X; ++i) {
434 own[i] = (int *)calloc(WORLD_Y, sizeof(int));
435 elev[i] = (int *)calloc(WORLD_Y, sizeof(int));
437 sectx = (int **)calloc(nc + ni, sizeof(int *));
438 secty = (int **)calloc(nc + ni, sizeof(int *));
439 sectc = (int **)calloc(nc + ni, sizeof(int *));
440 isecs = (int *)calloc(nc + ni, sizeof(int));
441 weight = (int *)calloc(max(sc, is * 2), sizeof(int));
442 dsea = (int *)calloc(max(sc, is * 2), sizeof(int));
443 dmoun = (int *)calloc(max(sc, is * 2), sizeof(int));
444 for (i = 0; i < nc; ++i) {
445 sectx[i] = (int *)calloc(sc, sizeof(int));
446 secty[i] = (int *)calloc(sc, sizeof(int));
447 sectc[i] = (int *)calloc(sc, sizeof(int));
449 for (i = nc; i < nc + ni; ++i) {
450 sectx[i] = (int *)calloc(is * 2, sizeof(int));
451 secty[i] = (int *)calloc(is * 2, sizeof(int));
452 sectc[i] = (int *)calloc(is * 2, sizeof(int));
461 int i, j, xx = 0, yy = 0;
466 for (i = 0; i < WORLD_X; ++i) {
467 for (j = 0; j < WORLD_Y; ++j) {
469 elev[i][j] = -INFINITY;
473 for (i = 0; i < nc; ++i, xx += 2) {
478 puts("fairland error: world not big enough for all the continents.\n");
485 for (i = 0; i < STABLE_CYCLE; ++i)
489 /****************************************************************************
490 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
491 ****************************************************************************/
493 /* How isolated is capital j?
496 iso(int j, int newx, int newy)
498 int i, md, d = WORLD_X + WORLD_Y;
500 for (i = 0; i < nc; ++i) {
503 md = mapdist(capx[i], capy[i], newx, newy);
511 /* Drift all the capitals
518 for (turns = 0; turns < DRIFT_MAX; ++turns) {
519 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
521 for (i = 0; i < nc; ++i)
527 /* Check to see if we have stabilized--can we stop drifting the capitals?
533 int i, isod, d = 0, stab = 1;
535 for (i = 0; i < nc; ++i) {
536 isod = iso(i, capx[i], capy[i]);
540 for (i = 0; i < STABLE_CYCLE; ++i)
544 mcc = (mcc + 1) % STABLE_CYCLE;
548 /* This routine does the actual drifting
554 int i, n, newx, newy;
556 for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
557 newx = new_x(capx[j] + dirx[i]);
558 newy = new_y(capy[j] + diry[i]);
559 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
567 /****************************************************************************
569 ****************************************************************************/
571 /* Look for a coastal sector of continent c
579 for (i = 0; i < secs; ++i) {
581 for (j = 0; j < 6; ++j)
582 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
587 /* Used for measuring distances
599 for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
602 return i > 1 || vector[0] > 0;
605 /* Test to see if we're allowed to grow there: the arguments di and id
608 try_to_grow(int c, int newx, int newy, int d)
612 for (i = 1; i <= d; ++i) {
613 for (j = 0; j < i; ++j)
618 for (j = 0; j < i; ++j) {
619 px = new_x(px + dirx[vector[j]]);
620 py = new_y(py + diry[vector[j]]);
622 if (own[px][py] != -1 &&
624 (DISTINCT_ISLANDS || own[px][py] < nc))
626 } while (next_vector(i));
628 sectx[c][secs] = newx;
629 secty[c][secs] = newy;
634 /* Move along the coast in a clockwise direction.
638 next_coast(int c, int x, int y, int *xp, int *yp)
640 int i, nx, ny, wat = 0;
648 for (i = 0; i < 12; ++i) {
649 nx = new_x(x + dirx[i % 6]);
650 ny = new_y(y + diry[i % 6]);
651 if (own[nx][ny] == -1)
653 if (wat && own[nx][ny] == c) {
661 /* Choose a sector to grow from
673 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
678 } while (i != starti);
680 printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n",
689 /* Grow continent c by 1 sector
693 grow_one_sector(int c)
695 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
697 spike = rnd(100) < sp;
698 if ((try1 = new_try(c)) == -1)
700 x = sx = sectx[c][try1];
701 y = sy = secty[c][try1];
706 for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
707 newx = new_x(x + dirx[i]);
708 newy = new_y(y + diry[i]);
709 if (own[newx][newy] == -1 &&
711 (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
712 own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
713 if (try_to_grow(c, newx, newy, c < nc ? di : id))
717 for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
718 newx = new_x(x + dirx[i]);
719 newy = new_y(y + diry[i]);
720 if (own[newx][newy] == -1)
721 if (try_to_grow(c, newx, newy, c < nc ? di : id))
724 next_coast(c, x, y, &x, &y);
726 } while (!done && coast_search < COAST_SEARCH_MAX &&
727 (secs == 1 || x != sx || y != sy));
728 if (!done && c < nc) {
729 qprint("fairland: error -- continent %c had no room to grow!\n",
731 fl_status |= STATUS_NO_ROOM;
736 /* Grow all the continents
739 grow_continents(void)
743 for (c = 0; c < nc; ++c) {
744 sectx[c][0] = capx[c];
745 secty[c][0] = capy[c];
746 own[sectx[c][0]][secty[c][0]] = c;
747 sectx[c][1] = new_x(capx[c] + 2);
748 secty[c][1] = capy[c];
749 own[sectx[c][1]][secty[c][1]] = c;
752 for (secs = 2; secs < sc && !fl_status; ++secs) {
753 for (c = 0; c < nc; ++c) {
759 qprint("Only managed to grow %d out of %d sectors.\n", secs, sc);
763 /****************************************************************************
765 ****************************************************************************/
767 /* Choose a place to start growing an island from
770 place_island(int c, int *xp, int *yp)
773 int ssy = rnd(WORLD_Y);
774 int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2);
776 if (ssx > WORLD_X - 2)
777 ssx = new_x(ssx + 2);
778 for (d = di + id; d >= id; --d) {
782 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
783 if (*xp >= WORLD_X) {
784 *yp = new_y(*yp + 1);
786 if (*xp == sx && *yp == sy)
789 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
796 /* Grow all the islands
804 for (c = nc; c < nc + ni; ++c) {
806 if (!place_island(c, &x, &y))
808 isiz = 1 + rnd(2 * is - 1);
812 } while (secs < isiz && grow_one_sector(c));
813 qprint(" %d(%d)", c - nc + 1, secs);
819 /****************************************************************************
821 ****************************************************************************/
823 create_elevations(void)
829 /* Generic function for finding the distance to the closest sea, land, or
833 distance_to_what(int x, int y, int flag)
837 for (d = 1; d < 5; ++d) {
838 for (j = 0; j < d; ++j)
843 for (j = 0; j < d; ++j) {
844 px = new_x(px + dirx[vector[j]]);
845 py = new_y(py + diry[vector[j]]);
848 case 0: /* distance to sea */
849 if (own[px][py] == -1)
852 case 1: /* distance to land */
853 if (own[px][py] != -1)
856 case 2: /* distance to mountain */
857 if (elev[px][py] == INFINITY)
861 } while (next_vector(d));
866 #define ELEV elev[sectx[c][i]][secty[c][i]]
867 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
868 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
870 /* Decide where the mountains go
875 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
878 for (c = 0; c < ctot; ++c) {
880 ns = (c < nc) ? sc : isecs[c];
881 nm = (pm * ns) / 100;
883 /* Place the mountains */
885 for (i = 0; i < ns; ++i) {
886 dsea[i] = distance_to_sea();
887 weight[i] = (total += (dsea[i] * dsea[i]));
890 for (k = nm, mountain_search = 0;
891 k && mountain_search < MOUNTAIN_SEARCH_MAX;
894 for (i = 0; i < ns; ++i)
895 if (r < weight[i] && ELEV == -INFINITY &&
897 ((!(capx[c] == sectx[c][i] &&
898 capy[c] == secty[c][i])) &&
899 (!(new_x(capx[c] + 2) == sectx[c][i] &&
900 capy[c] == secty[c][i]))))) {
907 /* Elevate land that is not mountain and not capital */
909 for (i = 0; i < ns; ++i)
910 dmoun[i] = distance_to_mountain();
911 dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
912 (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
914 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
917 for (i = 0; i < ns; ++i) {
918 if (ELEV != INFINITY &&
919 (c >= nc || ((!(capx[c] == sectx[c][i] &&
920 capy[c] == secty[c][i])) &&
921 (!(new_x(capx[c] + 2) == sectx[c][i] &&
922 capy[c] == secty[c][i]))))) {
923 h = 3 * (5 - dmoun[i]) + dsea[i];
933 if (newk >= HILLMIN && newk < PLATMIN)
937 elev[sectx[c][where]][secty[c][where]] = newk;
938 dsea[where] = -INFINITY;
939 dmoun[where] = INFINITY;
942 /* Elevate the mountains and capitals */
944 for (i = 0; i < ns; ++i) {
945 if (ELEV == INFINITY) {
947 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
949 ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) +
950 rnd((256 - HIGHMIN) / 2);
951 } else if ((c < nc &&
952 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
953 ((new_x(capx[c] + 2) == sectx[c][i] &&
954 capy[c] == secty[c][i])))
960 #define distance_to_land() distance_to_what(x, y, 1)
967 for (y = 0; y < WORLD_Y; ++y) {
968 for (x = y % 2; x < WORLD_X; x += 2) {
969 if (elev[x][y] == -INFINITY)
970 elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
975 /****************************************************************************
977 ****************************************************************************/
984 fert = LANDMIN - e + 40;
985 else if (e < FERT_MAX)
986 fert = (140 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
997 oil = (LANDMIN - e) * 2 + rnd(2);
998 else if (e <= OIL_MAX)
999 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1009 if (e >= IRON_MIN && e < HIGHMIN)
1010 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1020 if (e >= GOLD_MIN) {
1022 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1024 gold = 100 - 20 * HIGHMIN / e;
1035 if (e >= URAN_MIN && e < HIGHMIN)
1036 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1043 add_resources(struct sctstr *sct)
1045 sct->sct_fertil = set_fert(sct->sct_elev);
1046 sct->sct_oil = set_oil(sct->sct_elev);
1047 sct->sct_min = set_iron(sct->sct_elev);
1048 sct->sct_gmin = set_gold(sct->sct_elev);
1049 sct->sct_uran = set_uran(sct->sct_elev);
1052 /****************************************************************************
1053 DESIGNATE THE SECTORS
1054 ****************************************************************************/
1062 /* sct = §s[0][0]; */
1064 for (y = 0; y < YSIZE; y++) {
1065 for (x = 0; x < XSIZE; x++, sct++) {
1066 fl_sct_init(x * 2 + (y & 01), y, (s_char *)sct);
1067 total = elev[sct->sct_x][y];
1068 if (total < LANDMIN) {
1069 sct->sct_type = SCT_WATER;
1070 } else if (total < HILLMIN)
1071 sct->sct_type = SCT_RURAL;
1072 else if (total < PLATMIN)
1073 sct->sct_type = SCT_MOUNT;
1074 else if (total < HIGHMIN)
1075 sct->sct_type = SCT_RURAL;
1077 sct->sct_type = SCT_MOUNT;
1078 sct->sct_elev = total;
1079 sct->sct_newtype = sct->sct_type;
1085 for (c = 0; c < nc; ++c) {
1086 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_type = SCT_AIRPT;
1087 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_newtype = SCT_AIRPT;
1091 /****************************************************************************
1092 WRITE ALL THIS STUFF TO THE FILE
1093 ****************************************************************************/
1099 /* if ((n = write(the_file, sects, sizeof(sects))) < 0) { */
1100 if ((n = write(the_file, sectsbuf, YSIZE * XSIZE * sizeof(struct sctstr))) < 0) {
1101 perror(empfile[EF_SECTOR].file);
1104 if (n != (int)(YSIZE * XSIZE * sizeof(struct sctstr))) {
1105 printf("%s:partial write\n", empfile[EF_SECTOR].file);
1112 /****************************************************************************
1113 PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1114 ****************************************************************************/
1120 translate_continents();
1122 for (i = 0; i < WORLD_Y; ++i) {
1126 for (j = i % 2; j < WORLD_X; j += 2) {
1127 if (own[j][i] == -1)
1130 printf("%c ", map_symbol(j, i));
1136 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");
1139 /* Reorder the continents from top left to bottom right */
1141 translate_continents(void)
1143 int i, j, n = 0, k, gotit, c;
1144 int *trans, *trans_cont, *oldcapx, *oldcapy;
1146 trans = (int *)calloc(nc, sizeof(int));
1147 trans_cont = (int *)calloc(nc, sizeof(int));
1148 oldcapx = (int *)calloc(nc, sizeof(int));
1149 oldcapy = (int *)calloc(nc, sizeof(int));
1151 for (i = 0; i < WORLD_Y; ++i) {
1152 for (j = i % 2; j < WORLD_X; j += 2) {
1153 if (own[j][i] > -1 && own[j][i] < nc) {
1155 for (k = 0; k < n; ++k) {
1156 if (trans[k] == own[j][i])
1161 printf("fairland: BUG in translate continents! mail stevens@math.utoronto.ca\n");
1164 trans[n] = own[j][i];
1165 trans_cont[own[j][i]] = n;
1171 for (i = 0; i < WORLD_Y; ++i) {
1172 for (j = i % 2; j < WORLD_X; j += 2) {
1173 if (own[j][i] > -1 && own[j][i] < nc) {
1174 own[j][i] = trans_cont[own[j][i]];
1178 for (c = 0; c < nc; ++c) {
1179 oldcapx[c] = capx[c];
1180 oldcapy[c] = capy[c];
1182 for (c = 0; c < nc; ++c) {
1183 capx[c] = oldcapx[trans[c]];
1184 capy[c] = oldcapy[trans[c]];
1189 map_symbol(int x, int y)
1193 for (c = 0; c < nc; ++c)
1194 if ((x == capx[c] && y == capy[c])
1195 || (x == new_x(capx[c] + 2) && y == capy[c]))
1197 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
1198 || elev[x][y] >= HIGHMIN)
1200 return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
1203 /***************************************************************************
1204 WRITE A SCRIPT FOR PLACING CAPITALS
1205 ****************************************************************************/
1207 write_newcap_script(void)
1210 FILE *script = fopen(outfile, "w");
1213 printf("fairland: error, unable to write to %s.\n", outfile);
1217 for (c = 0; c < nc; ++c) {
1218 fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1);
1220 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1221 fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1223 fprintf(script, "add %d visitor visitor v i\n", c + 1);
1226 qprint("\n\nA script for adding all the countries can be found in \"%s\".\n",
1232 qprint(const char * const fmt, ...)
1238 vfprintf(stdout, fmt, ap);
1244 fl_sct_init(coord x, coord y, s_char *ptr)
1246 struct sctstr *sp = (struct sctstr *)ptr;
1248 sp->ef_type = EF_SECTOR;
1255 sp->sct_defense = 0;