2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2000, 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 */
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 static const char *outfile = "newcap_script";
96 /* mark the continents with a * so you can tell them
97 from the islands 1 = mark, 0 = don't mark. */
98 static int AIRPORT_MARKER = 0;
100 /* don't let the islands crash into each other.
101 1 = don't merge, 0 = merge. */
102 static int DISTINCT_ISLANDS = 1;
104 #define XSIZE ((WORLD_X) / 2) /* basically world x-y size */
105 #define YSIZE (WORLD_Y)
106 #define STABLE_CYCLE 4 /* stability required for perterbed capitals */
107 #define INFINITY 999 /* a number which means "BIG" */
109 /* these defines prevent infinite loops:
112 #define COAST_SEARCH_MAX 200 /* how many times do we look for a coast sector
113 when growing continents and islands */
114 #define DRIFT_BEFORE_CHECK ((WORLD_X + WORLD_Y)/2)
115 #define DRIFT_MAX ((WORLD_X + WORLD_Y)*2)
116 #define MOUNTAIN_SEARCH_MAX 1000 /* how long do we try to place mountains */
121 #define new_x(newx) (((newx) + WORLD_X) % WORLD_X)
122 #define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y)
124 #define max(a,b) (a>b?a:b)
127 #define SRANDOM srandom
130 #define RANDOM random
132 #define rnd(x) (RANDOM() % (x))
134 int secs; /* number of sectors grown */
135 int ctot; /* total number of continents and islands grown */
136 int *isecs; /* array of how large each island is */
138 int nc, sc, di, sp, pm, ni, is, id; /* the 8 arguments to this program */
139 unsigned long rnd_seed; /* optional seed can be passed as an argument */
140 int *capx, *capy; /* location of the nc capitals */
141 int *mc, mcc; /* array and counter used for stability
142 check when perturbing */
143 int spike; /* are we spiking? */
144 int mind; /* the final distance between capitals that
146 int dirx[] = { -2, -1, 1, 2, 1, -1 }; /* gyujnb */
147 int diry[] = { 0, -1, -1, 0, 1, 1 };
149 int **own; /* owner of the sector. -1 means water */
150 int **elev; /* elevation of the sectors */
151 int **sectx, **secty; /* the sectors for each continent */
152 int **sectc; /* which sectors are on the coast? */
153 int *vector; /* used for measuring distances */
154 int *weight; /* used for placing mountains */
155 int *dsea, *dmoun; /* the dist to the ocean and mountain */
156 int the_file; /* the file we write everything to */
157 struct sctstr **sects;
158 struct sctstr *sectsbuf;
159 int fl_status; /* is anything wrong? */
160 #define STATUS_NO_ROOM (1) /* there was no room to grow */
161 #define NUMTRIES 10 /* keep trying to grow this many times */
163 const char *numletter =
164 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
166 static void parse_args(int argc, char *argv[]);
167 static int allocate_memory(void);
168 static void init(void);
169 static int drift(void);
170 static void grow_continents(void);
171 static void create_elevations(void);
172 static void write_sects(void);
173 static int write_file(void);
174 static void output(void);
175 static int write_newcap_script(void);
176 static int stable(void);
177 static void elevate_land(void);
178 static void elevate_sea(void);
179 static void translate_continents(void);
180 static int map_symbol(int x, int y);
181 static void fl_sct_init(coord x, coord y, s_char *ptr);
183 static void print_vars(void);
184 static void fl_move(int);
185 static void next_coast(int c, int x, int y, int *xp, int *yp);
186 static void grow_islands(void);
188 /****************************************************************************
190 ****************************************************************************/
193 main(int argc, char *argv[])
198 char *config_file = NULL;
202 rnd_seed = time(NULL);
204 rnd_seed += getpid();
206 while ((opt = getopt(argc, argv, "ae:ioqs:R:")) != EOF) {
212 DISTINCT_ISLANDS = 0;
215 config_file = optarg;
227 rnd_seed = strtoul(optarg, NULL, 10);
233 if (config_file == NULL) {
234 sprintf(tbuf, "%s/econfig", datadir);
237 emp_config(config_file);
240 parse_args(argc - optind, argv + optind);
242 parse_args(argc - 1, argv + 1);
244 if (allocate_memory() == -1)
251 qprint("\ntry #%d (out of %d)...", i + 1, NUMTRIES);
252 qprint("\n\n #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
253 qprint("seed is %lu\n", rnd_seed);
254 qprint("placing capitals...\n");
256 qprint("fairland: unstable drift -- try increasisg DRIFT_MAX\n");
257 qprint("growing continents...\n");
259 } while (fl_status && ++i < NUMTRIES);
261 fputs("ERROR: World not large enough to hold continents\n",
265 qprint("growing islands:");
267 qprint("\nelevating land...\n");
269 qprint("designating sectors...\n");
271 qprint("adding resources...\n");
273 qprint("writing to sectors file...\n");
274 if (write_file() == -1)
277 write_newcap_script();
279 qprint("\t*** Resources have not been added ***\n");
288 puts("Creating a planet with:\n");
289 printf("%d continents\n", nc);
290 printf("continent size: %d\n", sc);
291 printf("number of islands: %d\n", ni);
292 printf("average size of islands: %d\n", is);
293 printf("spike: %d%%\n", sp);
294 printf("%d%% of land is mountain (each continent will have %d mountains)\n",
295 pm, (pm * sc) / 100);
296 printf("minimum distance between continents: %d\n", di);
297 printf("minimum distance from islands to continents: %d\n", id);
298 printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
306 for (i = 1; i * i < n * 10000; ++i) ;
307 return (i + 50) / 100;
310 /****************************************************************************
311 PARSE COMMAND LINE ARGUMENTS
312 ****************************************************************************/
315 parse_args(int argc, char *argv[])
317 if (argc < 2 || argc > 8) {
318 puts("fairland syntax:\n");
319 puts("fairland [-e config] [-aiqo] [-s script] [-R seed] <nc> <sc> [<ni>] [<is>] [<sp>] [<pm>] [<di>] [<id>]");
320 puts("-q = quiet, -o = no ore produced");
321 puts("-a = Airport marker for continents, -i = islands not distinct");
322 puts("-R = seed to use for random, -e = read config file");
323 printf("-s = name of script (default %s)\n",
325 puts("nc = number of continents [MANDATORY]");
326 puts("sc = continent size [MANDATORY]");
327 puts("ni = number of islands (default = nc)");
328 puts("is = average size of islands (default = sc/2)");
329 printf("sp = spike percentage: 0 = round, 100 = snake (default = %d)\n",
331 printf("pm = the percentage of land that is mountain (default = %d)\n",
333 printf("di = the minimum distance between continents (default = %d)\n",
335 printf("id = minimum distance from islands to continents (default = %d)\n",
341 puts("fairland: error -- number of continents must be > 0");
347 puts("fairland: error -- size of continents must be > 0");
375 pm = DEFAULT_MOUNTAIN;
382 di = DEFAULT_CONTDIST;
385 puts("fairland: error -- distance between continents must be >= 0");
388 if (di > WORLD_X / 2 || di > WORLD_Y / 2) {
389 puts("fairland: error -- distance between continents too large");
396 id = DEFAULT_ISLDIST;
398 puts("fairland: error -- distance from islands to continents must be >= 0");
401 if (id > WORLD_X || id > WORLD_Y) {
402 puts("fairland: error -- distance from islands to continents too large");
405 if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
406 puts("fairland: error -- world not big enough to fit continents.");
407 puts("arguments must satisfy:");
408 puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
413 /****************************************************************************
414 VARIABLE INITIALIZATION
415 ****************************************************************************/
418 allocate_memory(void)
424 open(empfile[EF_SECTOR].file, O_RDWR | O_CREAT | O_TRUNC, 0660);
427 open(empfile[EF_SECTOR].file,
428 O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0660);
431 perror(empfile[EF_SECTOR].file);
435 (struct sctstr *)calloc((YSIZE * XSIZE), sizeof(struct sctstr));
436 sects = (struct sctstr **)calloc(YSIZE, sizeof(struct sctstr *));
437 for (i = 0; i < YSIZE; i++)
438 sects[i] = §sbuf[XSIZE * i];
439 capx = (int *)calloc(nc, sizeof(int));
440 capy = (int *)calloc(nc, sizeof(int));
441 vector = (int *)calloc(WORLD_X + WORLD_Y, sizeof(int));
442 mc = (int *)calloc(STABLE_CYCLE, sizeof(int));
443 own = (int **)calloc(WORLD_X, sizeof(int *));
444 elev = (int **)calloc(WORLD_X, sizeof(int *));
445 for (i = 0; i < WORLD_X; ++i) {
446 own[i] = (int *)calloc(WORLD_Y, sizeof(int));
447 elev[i] = (int *)calloc(WORLD_Y, sizeof(int));
449 sectx = (int **)calloc(nc + ni, sizeof(int *));
450 secty = (int **)calloc(nc + ni, sizeof(int *));
451 sectc = (int **)calloc(nc + ni, sizeof(int *));
452 isecs = (int *)calloc(nc + ni, sizeof(int));
453 weight = (int *)calloc(max(sc, is * 2), sizeof(int));
454 dsea = (int *)calloc(max(sc, is * 2), sizeof(int));
455 dmoun = (int *)calloc(max(sc, is * 2), sizeof(int));
456 for (i = 0; i < nc; ++i) {
457 sectx[i] = (int *)calloc(sc, sizeof(int));
458 secty[i] = (int *)calloc(sc, sizeof(int));
459 sectc[i] = (int *)calloc(sc, sizeof(int));
461 for (i = nc; i < nc + ni; ++i) {
462 sectx[i] = (int *)calloc(is * 2, sizeof(int));
463 secty[i] = (int *)calloc(is * 2, sizeof(int));
464 sectc[i] = (int *)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, xx += 2) {
490 puts("fairland error: world not big enough for all the continents.\n");
497 for (i = 0; i < STABLE_CYCLE; ++i)
501 /****************************************************************************
502 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
503 ****************************************************************************/
505 /* How isolated is capital j?
508 iso(int j, int newx, int newy)
510 int i, md, d = WORLD_X + WORLD_Y;
512 for (i = 0; i < nc; ++i) {
515 md = mapdist(capx[i], capy[i], newx, newy);
523 /* Drift all the capitals
530 for (turns = 0; turns < DRIFT_MAX; ++turns) {
531 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
533 for (i = 0; i < nc; ++i)
539 /* Check to see if we have stabilized--can we stop drifting the capitals?
545 int i, isod, d = 0, stab = 1;
547 for (i = 0; i < nc; ++i) {
548 isod = iso(i, capx[i], capy[i]);
552 for (i = 0; i < STABLE_CYCLE; ++i)
556 mcc = (mcc + 1) % STABLE_CYCLE;
560 /* This routine does the actual drifting
566 int i, n, newx, newy;
568 for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
569 newx = new_x(capx[j] + dirx[i]);
570 newy = new_y(capy[j] + diry[i]);
571 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
579 /****************************************************************************
581 ****************************************************************************/
583 /* Look for a coastal sector of continent c
591 for (i = 0; i < secs; ++i) {
593 for (j = 0; j < 6; ++j)
594 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
599 /* Used for measuring distances
611 for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
614 return i > 1 || vector[0] > 0;
617 /* Test to see if we're allowed to grow there: the arguments di and id
620 try_to_grow(int c, int newx, int newy, int d)
624 for (i = 1; i <= d; ++i) {
625 for (j = 0; j < i; ++j)
630 for (j = 0; j < i; ++j) {
631 px = new_x(px + dirx[vector[j]]);
632 py = new_y(py + diry[vector[j]]);
634 if (own[px][py] != -1 &&
636 (DISTINCT_ISLANDS || own[px][py] < nc))
638 } while (next_vector(i));
640 sectx[c][secs] = newx;
641 secty[c][secs] = newy;
646 /* Move along the coast in a clockwise direction.
650 next_coast(int c, int x, int y, int *xp, int *yp)
652 int i, nx, ny, wat = 0;
660 for (i = 0; i < 12; ++i) {
661 nx = new_x(x + dirx[i % 6]);
662 ny = new_y(y + diry[i % 6]);
663 if (own[nx][ny] == -1)
665 if (wat && own[nx][ny] == c) {
673 /* Choose a sector to grow from
685 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
690 } while (i != starti);
692 printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n",
701 /* Grow continent c by 1 sector
705 grow_one_sector(int c)
707 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
709 spike = rnd(100) < sp;
710 if ((try1 = new_try(c)) == -1)
712 x = sx = sectx[c][try1];
713 y = sy = secty[c][try1];
718 for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
719 newx = new_x(x + dirx[i]);
720 newy = new_y(y + diry[i]);
721 if (own[newx][newy] == -1 &&
723 (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
724 own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
725 if (try_to_grow(c, newx, newy, c < nc ? di : id))
729 for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
730 newx = new_x(x + dirx[i]);
731 newy = new_y(y + diry[i]);
732 if (own[newx][newy] == -1)
733 if (try_to_grow(c, newx, newy, c < nc ? di : id))
736 next_coast(c, x, y, &x, &y);
738 } while (!done && coast_search < COAST_SEARCH_MAX &&
739 (secs == 1 || x != sx || y != sy));
740 if (!done && c < nc) {
741 qprint("fairland: error -- continent %c had no room to grow!\n",
743 fl_status |= STATUS_NO_ROOM;
748 /* Grow all the continents
751 grow_continents(void)
755 for (c = 0; c < nc; ++c) {
756 sectx[c][0] = capx[c];
757 secty[c][0] = capy[c];
758 own[sectx[c][0]][secty[c][0]] = c;
759 sectx[c][1] = new_x(capx[c] + 2);
760 secty[c][1] = capy[c];
761 own[sectx[c][1]][secty[c][1]] = c;
764 for (secs = 2; secs < sc && !fl_status; ++secs) {
765 for (c = 0; c < nc; ++c) {
771 qprint("Only managed to grow %d out of %d sectors.\n", secs, sc);
775 /****************************************************************************
777 ****************************************************************************/
779 /* Choose a place to start growing an island from
782 place_island(int c, int *xp, int *yp)
785 int ssy = rnd(WORLD_Y);
786 int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2);
788 if (ssx > WORLD_X - 2)
789 ssx = new_x(ssx + 2);
790 for (d = di + id; d >= id; --d) {
794 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
795 if (*xp >= WORLD_X) {
796 *yp = new_y(*yp + 1);
798 if (*xp == sx && *yp == sy)
801 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
808 /* Grow all the islands
816 for (c = nc; c < nc + ni; ++c) {
818 if (!place_island(c, &x, &y))
820 isiz = 1 + rnd(2 * is - 1);
824 } while (secs < isiz && grow_one_sector(c));
825 qprint(" %d(%d)", c - nc + 1, secs);
831 /****************************************************************************
833 ****************************************************************************/
835 create_elevations(void)
841 /* Generic function for finding the distance to the closest sea, land, or
845 distance_to_what(int x, int y, int flag)
849 for (d = 1; d < 5; ++d) {
850 for (j = 0; j < d; ++j)
855 for (j = 0; j < d; ++j) {
856 px = new_x(px + dirx[vector[j]]);
857 py = new_y(py + diry[vector[j]]);
860 case 0: /* distance to sea */
861 if (own[px][py] == -1)
864 case 1: /* distance to land */
865 if (own[px][py] != -1)
868 case 2: /* distance to mountain */
869 if (elev[px][py] == INFINITY)
873 } while (next_vector(d));
878 #define ELEV elev[sectx[c][i]][secty[c][i]]
879 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
880 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
882 /* Decide where the mountains go
887 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
890 for (c = 0; c < ctot; ++c) {
892 ns = (c < nc) ? sc : isecs[c];
893 nm = (pm * ns) / 100;
895 /* Place the mountains */
897 for (i = 0; i < ns; ++i) {
898 dsea[i] = distance_to_sea();
899 weight[i] = (total += (dsea[i] * dsea[i]));
902 for (k = nm, mountain_search = 0;
903 k && mountain_search < MOUNTAIN_SEARCH_MAX;
906 for (i = 0; i < ns; ++i)
907 if (r < weight[i] && ELEV == -INFINITY &&
909 ((!(capx[c] == sectx[c][i] &&
910 capy[c] == secty[c][i])) &&
911 (!(new_x(capx[c] + 2) == sectx[c][i] &&
912 capy[c] == secty[c][i]))))) {
919 /* Elevate land that is not mountain and not capital */
921 for (i = 0; i < ns; ++i)
922 dmoun[i] = distance_to_mountain();
923 dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
924 (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
926 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
929 for (i = 0; i < ns; ++i) {
930 if (ELEV != INFINITY &&
931 (c >= nc || ((!(capx[c] == sectx[c][i] &&
932 capy[c] == secty[c][i])) &&
933 (!(new_x(capx[c] + 2) == sectx[c][i] &&
934 capy[c] == secty[c][i]))))) {
935 h = 3 * (5 - dmoun[i]) + dsea[i];
945 if (newk >= HILLMIN && newk < PLATMIN)
949 elev[sectx[c][where]][secty[c][where]] = newk;
950 dsea[where] = -INFINITY;
951 dmoun[where] = INFINITY;
954 /* Elevate the mountains and capitals */
956 for (i = 0; i < ns; ++i) {
957 if (ELEV == INFINITY) {
959 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
961 ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) +
962 rnd((256 - HIGHMIN) / 2);
963 } else if ((c < nc &&
964 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
965 ((new_x(capx[c] + 2) == sectx[c][i] &&
966 capy[c] == secty[c][i])))
972 #define distance_to_land() distance_to_what(x, y, 1)
979 for (y = 0; y < WORLD_Y; ++y) {
980 for (x = y % 2; x < WORLD_X; x += 2) {
981 if (elev[x][y] == -INFINITY)
982 elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
987 /****************************************************************************
989 ****************************************************************************/
996 fert = LANDMIN - e + 40;
997 else if (e < FERT_MAX)
998 fert = (140 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
1009 oil = (LANDMIN - e) * 2 + rnd(2);
1010 else if (e <= OIL_MAX)
1011 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1021 if (e >= IRON_MIN && e < HIGHMIN)
1022 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1032 if (e >= GOLD_MIN) {
1034 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1036 gold = 100 - 20 * HIGHMIN / e;
1047 if (e >= URAN_MIN && e < HIGHMIN)
1048 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1055 add_resources(struct sctstr *sct)
1057 sct->sct_fertil = set_fert(sct->sct_elev);
1058 sct->sct_oil = set_oil(sct->sct_elev);
1059 sct->sct_min = set_iron(sct->sct_elev);
1060 sct->sct_gmin = set_gold(sct->sct_elev);
1061 sct->sct_uran = set_uran(sct->sct_elev);
1064 /****************************************************************************
1065 DESIGNATE THE SECTORS
1066 ****************************************************************************/
1071 register struct sctstr *sct;
1074 /* sct = §s[0][0]; */
1076 for (y = 0; y < YSIZE; y++) {
1077 for (x = 0; x < XSIZE; x++, sct++) {
1078 fl_sct_init(x * 2 + (y & 01), y, (s_char *)sct);
1079 total = elev[sct->sct_x][y];
1080 if (total < LANDMIN) {
1081 sct->sct_type = SCT_WATER;
1082 } else if (total < HILLMIN)
1083 sct->sct_type = SCT_RURAL;
1084 else if (total < PLATMIN)
1085 sct->sct_type = SCT_MOUNT;
1086 else if (total < HIGHMIN)
1087 sct->sct_type = SCT_RURAL;
1089 sct->sct_type = SCT_MOUNT;
1090 sct->sct_elev = total;
1091 sct->sct_newtype = sct->sct_type;
1097 for (c = 0; c < nc; ++c) {
1098 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_type = SCT_AIRPT;
1099 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_newtype = SCT_AIRPT;
1103 /****************************************************************************
1104 WRITE ALL THIS STUFF TO THE FILE
1105 ****************************************************************************/
1111 /* if ((n = write(the_file, sects, sizeof(sects))) < 0) { */
1112 if ((n = write(the_file, sectsbuf, YSIZE * XSIZE * sizeof(struct sctstr))) < 0) {
1113 perror(empfile[EF_SECTOR].file);
1116 if (n != (int)(YSIZE * XSIZE * sizeof(struct sctstr))) {
1117 printf("%s:partial write\n", empfile[EF_SECTOR].file);
1124 /****************************************************************************
1125 PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1126 ****************************************************************************/
1132 translate_continents();
1134 for (i = 0; i < WORLD_Y; ++i) {
1138 for (j = i % 2; j < WORLD_X; j += 2) {
1139 if (own[j][i] == -1)
1142 printf("%c ", map_symbol(j, i));
1148 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");
1151 /* Reorder the continents from top left to bottom right */
1153 translate_continents(void)
1155 int i, j, n = 0, k, gotit, c;
1156 int *trans, *trans_cont, *oldcapx, *oldcapy;
1158 trans = (int *)calloc(nc, sizeof(int));
1159 trans_cont = (int *)calloc(nc, sizeof(int));
1160 oldcapx = (int *)calloc(nc, sizeof(int));
1161 oldcapy = (int *)calloc(nc, sizeof(int));
1163 for (i = 0; i < WORLD_Y; ++i) {
1164 for (j = i % 2; j < WORLD_X; j += 2) {
1165 if (own[j][i] > -1 && own[j][i] < nc) {
1167 for (k = 0; k < n; ++k) {
1168 if (trans[k] == own[j][i])
1173 printf("fairland: BUG in translate continents! mail stevens@math.utoronto.ca\n");
1176 trans[n] = own[j][i];
1177 trans_cont[own[j][i]] = n;
1183 for (i = 0; i < WORLD_Y; ++i) {
1184 for (j = i % 2; j < WORLD_X; j += 2) {
1185 if (own[j][i] > -1 && own[j][i] < nc) {
1186 own[j][i] = trans_cont[own[j][i]];
1190 for (c = 0; c < nc; ++c) {
1191 oldcapx[c] = capx[c];
1192 oldcapy[c] = capy[c];
1194 for (c = 0; c < nc; ++c) {
1195 capx[c] = oldcapx[trans[c]];
1196 capy[c] = oldcapy[trans[c]];
1201 map_symbol(int x, int y)
1205 for (c = 0; c < nc; ++c)
1206 if ((x == capx[c] && y == capy[c])
1207 || (x == new_x(capx[c] + 2) && y == capy[c]))
1209 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
1210 || elev[x][y] >= HIGHMIN)
1212 return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
1215 /***************************************************************************
1216 WRITE A SCRIPT FOR PLACING CAPITALS
1217 ****************************************************************************/
1219 write_newcap_script(void)
1222 FILE *script = fopen(outfile, "w");
1225 printf("fairland: error, unable to write to %s.\n", outfile);
1229 for (c = 0; c < nc; ++c) {
1230 fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1);
1232 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1233 fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1235 fprintf(script, "add %d visitor visitor v i\n", c + 1);
1238 qprint("\n\nA script for adding all the countries can be found in \"%s\".\n",
1244 qprint(const char * const fmt, ...)
1250 vfprintf(stdout, fmt, ap);
1256 fl_sct_init(coord x, coord y, s_char *ptr)
1258 struct sctstr *sp = (struct sctstr *)ptr;
1260 sp->ef_type = EF_SECTOR;
1267 sp->sct_defense = 0;