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 */
83 #include "prototypes.h"
85 /* do not change these 4 defines */
86 #define LANDMIN 1 /* plate altitude for normal land */
87 #define HILLMIN 34 /* plate altitude for hills */
88 #define PLATMIN 36 /* plate altitude for plateau */
89 #define HIGHMIN 98 /* plate altitude for mountains */
91 static void qprint(const char *str);
93 static const char *outfile = "newcap_script";
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 #define XSIZE ((WORLD_X) / 2) /* basically world x-y size */
103 #define YSIZE (WORLD_Y)
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)
122 #define max(a,b) (a>b?a:b)
124 #define rnd(x) (random() % (x))
126 int secs; /* number of sectors grown */
127 int ctot; /* total number of continents and islands grown */
128 int *isecs; /* array of how large each island is */
130 int nc, sc, di, sp, pm, ni, is, id; /* the 8 arguments to this program */
131 unsigned long rnd_seed; /* optional seed can be passed as an argument */
132 int *capx, *capy; /* location of the nc capitals */
133 int *mc, mcc; /* array and counter used for stability
134 check when perturbing */
135 int spike; /* are we spiking? */
136 int mind; /* the final distance between capitals that
138 int dirx[] = { -2, -1, 1, 2, 1, -1 }; /* gyujnb */
139 int diry[] = { 0, -1, -1, 0, 1, 1 };
141 int **own; /* owner of the sector. -1 means water */
142 int **elev; /* elevation of the sectors */
143 int **sectx, **secty; /* the sectors for each continent */
144 int **sectc; /* which sectors are on the coast? */
145 int *vector; /* used for measuring distances */
146 int *weight; /* used for placing mountains */
147 int *dsea, *dmoun; /* the dist to the ocean and mountain */
148 int the_file; /* the file we write everything to */
149 struct sctstr **sects;
150 struct sctstr *sectsbuf;
151 int fl_status; /* is anything wrong? */
152 #define STATUS_NO_ROOM (1) /* there was no room to grow */
153 #define NUMTRIES 10 /* keep trying to grow this many times */
155 const char *numletter =
156 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
158 static void parse_args(int argc, char *argv[]);
159 static int allocate_memory(void);
160 static void init(void);
161 static int drift(void);
162 static void grow_continents(void);
163 static void create_elevations(void);
164 static void write_sects(void);
165 static int write_file(void);
166 static void output(void);
167 static int write_newcap_script(void);
168 static int stable(void);
169 static void elevate_land(void);
170 static void elevate_sea(void);
171 static void translate_continents(void);
172 static int map_symbol(int x, int y);
173 static void fl_sct_init(coord x, coord y, s_char *ptr);
175 static void print_vars(void);
176 static void fl_move(int);
177 static void next_coast(int c, int x, int y, int *xp, int *yp);
178 static void grow_islands(void);
180 /****************************************************************************
182 ****************************************************************************/
185 main(int argc, char *argv[])
190 char *config_file = NULL;
194 rnd_seed = time(NULL);
196 rnd_seed += getpid();
198 while ((opt = getopt(argc, argv, "ae:ioqs:R:")) != EOF) {
204 DISTINCT_ISLANDS = 0;
207 config_file = optarg;
219 rnd_seed = strtoul(optarg, NULL, 10);
225 if (config_file == NULL) {
226 sprintf(tbuf, "%s/econfig", datadir);
229 emp_config(config_file);
232 parse_args(argc - optind, argv + optind);
234 parse_args(argc - 1, argv + 1);
236 if (allocate_memory() == -1)
243 printf("\ntry #%d (out of %d)...", i + 1, NUMTRIES);
244 qprint("\n\n #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
246 printf("seed is %lu\n", rnd_seed);
247 qprint("placing capitals...\n");
249 qprint("fairland: unstable drift -- try increasisg DRIFT_MAX\n");
250 qprint("growing continents...\n");
252 } while (fl_status && ++i < NUMTRIES);
254 fputs("ERROR: World not large enough to hold continents\n",
258 qprint("growing islands:");
260 qprint("\nelevating land...\n");
262 qprint("designating sectors...\n");
264 qprint("adding resources...\n");
266 qprint("writing to sectors file...\n");
267 if (write_file() == -1)
270 write_newcap_script();
272 printf("\t*** Resources have not been added ***\n");
281 puts("Creating a planet with:\n");
282 printf("%d continents\n", nc);
283 printf("continent size: %d\n", sc);
284 printf("number of islands: %d\n", ni);
285 printf("average size of islands: %d\n", is);
286 printf("spike: %d%%\n", sp);
287 printf("%d%% of land is mountain (each continent will have %d mountains)\n",
288 pm, (pm * sc) / 100);
289 printf("minimum distance between continents: %d\n", di);
290 printf("minimum distance from islands to continents: %d\n", id);
291 printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
299 for (i = 1; i * i < n * 10000; ++i) ;
300 return (i + 50) / 100;
303 /****************************************************************************
304 PARSE COMMAND LINE ARGUMENTS
305 ****************************************************************************/
308 parse_args(int argc, char *argv[])
310 if (argc < 2 || argc > 8) {
311 puts("fairland syntax:\n");
312 puts("fairland [-e config] [-aiqo] [-s script] [-R seed] <nc> <sc> [<ni>] [<is>] [<sp>] [<pm>] [<di>] [<id>]");
313 puts("-q = quiet, -o = no ore produced");
314 puts("-a = Airport marker for continents, -i = islands not distinct");
315 puts("-R = seed to use for random, -e = read config file");
316 printf("-s = name of script (default %s)\n",
318 puts("nc = number of continents [MANDATORY]");
319 puts("sc = continent size [MANDATORY]");
320 puts("ni = number of islands (default = nc)");
321 puts("is = average size of islands (default = sc/2)");
322 printf("sp = spike percentage: 0 = round, 100 = snake (default = %d)\n",
324 printf("pm = the percentage of land that is mountain (default = %d)\n",
326 printf("di = the minimum distance between continents (default = %d)\n",
328 printf("id = minimum distance from islands to continents (default = %d)\n",
334 puts("fairland: error -- number of continents must be > 0");
340 puts("fairland: error -- size of continents must be > 0");
368 pm = DEFAULT_MOUNTAIN;
375 di = DEFAULT_CONTDIST;
378 puts("fairland: error -- distance between continents must be >= 0");
381 if (di > WORLD_X / 2 || di > WORLD_Y / 2) {
382 puts("fairland: error -- distance between continents too large");
389 id = DEFAULT_ISLDIST;
391 puts("fairland: error -- distance from islands to continents must be >= 0");
394 if (id > WORLD_X || id > WORLD_Y) {
395 puts("fairland: error -- distance from islands to continents too large");
398 if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
399 puts("fairland: error -- world not big enough to fit continents.");
400 puts("arguments must satisfy:");
401 puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
406 /****************************************************************************
407 VARIABLE INITIALIZATION
408 ****************************************************************************/
411 allocate_memory(void)
417 open(empfile[EF_SECTOR].file, O_RDWR | O_CREAT | O_TRUNC, 0660);
420 open(empfile[EF_SECTOR].file,
421 O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0660);
424 perror(empfile[EF_SECTOR].file);
428 (struct sctstr *)calloc((YSIZE * XSIZE), sizeof(struct sctstr));
429 sects = (struct sctstr **)calloc(YSIZE, sizeof(struct sctstr *));
430 for (i = 0; i < YSIZE; i++)
431 sects[i] = §sbuf[XSIZE * i];
432 capx = (int *)calloc(nc, sizeof(int));
433 capy = (int *)calloc(nc, sizeof(int));
434 vector = (int *)calloc(WORLD_X + WORLD_Y, sizeof(int));
435 mc = (int *)calloc(STABLE_CYCLE, sizeof(int));
436 own = (int **)calloc(WORLD_X, sizeof(int *));
437 elev = (int **)calloc(WORLD_X, sizeof(int *));
438 for (i = 0; i < WORLD_X; ++i) {
439 own[i] = (int *)calloc(WORLD_Y, sizeof(int));
440 elev[i] = (int *)calloc(WORLD_Y, sizeof(int));
442 sectx = (int **)calloc(nc + ni, sizeof(int *));
443 secty = (int **)calloc(nc + ni, sizeof(int *));
444 sectc = (int **)calloc(nc + ni, sizeof(int *));
445 isecs = (int *)calloc(nc + ni, sizeof(int));
446 weight = (int *)calloc(max(sc, is * 2), sizeof(int));
447 dsea = (int *)calloc(max(sc, is * 2), sizeof(int));
448 dmoun = (int *)calloc(max(sc, is * 2), sizeof(int));
449 for (i = 0; i < nc; ++i) {
450 sectx[i] = (int *)calloc(sc, sizeof(int));
451 secty[i] = (int *)calloc(sc, sizeof(int));
452 sectc[i] = (int *)calloc(sc, sizeof(int));
454 for (i = nc; i < nc + ni; ++i) {
455 sectx[i] = (int *)calloc(is * 2, sizeof(int));
456 secty[i] = (int *)calloc(is * 2, sizeof(int));
457 sectc[i] = (int *)calloc(is * 2, sizeof(int));
466 int i, j, xx = 0, yy = 0;
471 for (i = 0; i < WORLD_X; ++i) {
472 for (j = 0; j < WORLD_Y; ++j) {
474 elev[i][j] = -INFINITY;
478 for (i = 0; i < nc; ++i, xx += 2) {
483 puts("fairland error: world not big enough for all the continents.\n");
490 for (i = 0; i < STABLE_CYCLE; ++i)
494 /****************************************************************************
495 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
496 ****************************************************************************/
498 /* How isolated is capital j?
501 iso(int j, int newx, int newy)
503 int i, md, d = WORLD_X + WORLD_Y;
505 for (i = 0; i < nc; ++i) {
508 md = mapdist(capx[i], capy[i], newx, newy);
516 /* Drift all the capitals
523 for (turns = 0; turns < DRIFT_MAX; ++turns) {
524 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
526 for (i = 0; i < nc; ++i)
532 /* Check to see if we have stabilized--can we stop drifting the capitals?
538 int i, isod, d = 0, stab = 1;
540 for (i = 0; i < nc; ++i) {
541 isod = iso(i, capx[i], capy[i]);
545 for (i = 0; i < STABLE_CYCLE; ++i)
549 mcc = (mcc + 1) % STABLE_CYCLE;
553 /* This routine does the actual drifting
559 int i, n, newx, newy;
561 for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
562 newx = new_x(capx[j] + dirx[i]);
563 newy = new_y(capy[j] + diry[i]);
564 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
572 /****************************************************************************
574 ****************************************************************************/
576 /* Look for a coastal sector of continent c
584 for (i = 0; i < secs; ++i) {
586 for (j = 0; j < 6; ++j)
587 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
592 /* Used for measuring distances
604 for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
607 return i > 1 || vector[0] > 0;
610 /* Test to see if we're allowed to grow there: the arguments di and id
613 try_to_grow(int c, int newx, int newy, int d)
617 for (i = 1; i <= d; ++i) {
618 for (j = 0; j < i; ++j)
623 for (j = 0; j < i; ++j) {
624 px = new_x(px + dirx[vector[j]]);
625 py = new_y(py + diry[vector[j]]);
627 if (own[px][py] != -1 &&
629 (DISTINCT_ISLANDS || own[px][py] < nc))
631 } while (next_vector(i));
633 sectx[c][secs] = newx;
634 secty[c][secs] = newy;
639 /* Move along the coast in a clockwise direction.
643 next_coast(int c, int x, int y, int *xp, int *yp)
645 int i, nx, ny, wat = 0;
653 for (i = 0; i < 12; ++i) {
654 nx = new_x(x + dirx[i % 6]);
655 ny = new_y(y + diry[i % 6]);
656 if (own[nx][ny] == -1)
658 if (wat && own[nx][ny] == c) {
666 /* Choose a sector to grow from
678 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
683 } while (i != starti);
685 printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n",
694 /* Grow continent c by 1 sector
698 grow_one_sector(int c)
700 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
702 spike = rnd(100) < sp;
703 if ((try1 = new_try(c)) == -1)
705 x = sx = sectx[c][try1];
706 y = sy = secty[c][try1];
711 for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
712 newx = new_x(x + dirx[i]);
713 newy = new_y(y + diry[i]);
714 if (own[newx][newy] == -1 &&
716 (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
717 own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
718 if (try_to_grow(c, newx, newy, c < nc ? di : id))
722 for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
723 newx = new_x(x + dirx[i]);
724 newy = new_y(y + diry[i]);
725 if (own[newx][newy] == -1)
726 if (try_to_grow(c, newx, newy, c < nc ? di : id))
729 next_coast(c, x, y, &x, &y);
731 } while (!done && coast_search < COAST_SEARCH_MAX &&
732 (secs == 1 || x != sx || y != sy));
733 if (!done && c < nc) {
735 printf("fairland: error -- continent %c had no room to grow!\n",
737 fl_status |= STATUS_NO_ROOM;
742 /* Grow all the continents
745 grow_continents(void)
749 for (c = 0; c < nc; ++c) {
750 sectx[c][0] = capx[c];
751 secty[c][0] = capy[c];
752 own[sectx[c][0]][secty[c][0]] = c;
753 sectx[c][1] = new_x(capx[c] + 2);
754 secty[c][1] = capy[c];
755 own[sectx[c][1]][secty[c][1]] = c;
758 for (secs = 2; secs < sc && !fl_status; ++secs) {
759 for (c = 0; c < nc; ++c) {
764 if (fl_status && !quiet)
765 printf("Only managed to grow %d out of %d sectors.\n", secs, sc);
769 /****************************************************************************
771 ****************************************************************************/
773 /* Choose a place to start growing an island from
776 place_island(int c, int *xp, int *yp)
779 int ssy = rnd(WORLD_Y);
780 int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2);
782 if (ssx > WORLD_X - 2)
783 ssx = new_x(ssx + 2);
784 for (d = di + id; d >= id; --d) {
788 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
789 if (*xp >= WORLD_X) {
790 *yp = new_y(*yp + 1);
792 if (*xp == sx && *yp == sy)
795 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
802 /* Grow all the islands
810 for (c = nc; c < nc + ni; ++c) {
812 if (!place_island(c, &x, &y))
814 isiz = 1 + rnd(2 * is - 1);
818 } while (secs < isiz && grow_one_sector(c));
820 printf(" %d(%d)", c - nc + 1, secs);
826 /****************************************************************************
828 ****************************************************************************/
830 create_elevations(void)
836 /* Generic function for finding the distance to the closest sea, land, or
840 distance_to_what(int x, int y, int flag)
844 for (d = 1; d < 5; ++d) {
845 for (j = 0; j < d; ++j)
850 for (j = 0; j < d; ++j) {
851 px = new_x(px + dirx[vector[j]]);
852 py = new_y(py + diry[vector[j]]);
855 case 0: /* distance to sea */
856 if (own[px][py] == -1)
859 case 1: /* distance to land */
860 if (own[px][py] != -1)
863 case 2: /* distance to mountain */
864 if (elev[px][py] == INFINITY)
868 } while (next_vector(d));
873 #define ELEV elev[sectx[c][i]][secty[c][i]]
874 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
875 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
877 /* Decide where the mountains go
882 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
885 for (c = 0; c < ctot; ++c) {
887 ns = (c < nc) ? sc : isecs[c];
888 nm = (pm * ns) / 100;
890 /* Place the mountains */
892 for (i = 0; i < ns; ++i) {
893 dsea[i] = distance_to_sea();
894 weight[i] = (total += (dsea[i] * dsea[i]));
897 for (k = nm, mountain_search = 0;
898 k && mountain_search < MOUNTAIN_SEARCH_MAX;
901 for (i = 0; i < ns; ++i)
902 if (r < weight[i] && ELEV == -INFINITY &&
904 ((!(capx[c] == sectx[c][i] &&
905 capy[c] == secty[c][i])) &&
906 (!(new_x(capx[c] + 2) == sectx[c][i] &&
907 capy[c] == secty[c][i]))))) {
914 /* Elevate land that is not mountain and not capital */
916 for (i = 0; i < ns; ++i)
917 dmoun[i] = distance_to_mountain();
918 dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
919 (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
921 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
924 for (i = 0; i < ns; ++i) {
925 if (ELEV != INFINITY &&
926 (c >= nc || ((!(capx[c] == sectx[c][i] &&
927 capy[c] == secty[c][i])) &&
928 (!(new_x(capx[c] + 2) == sectx[c][i] &&
929 capy[c] == secty[c][i]))))) {
930 h = 3 * (5 - dmoun[i]) + dsea[i];
940 if (newk >= HILLMIN && newk < PLATMIN)
944 elev[sectx[c][where]][secty[c][where]] = newk;
945 dsea[where] = -INFINITY;
946 dmoun[where] = INFINITY;
949 /* Elevate the mountains and capitals */
951 for (i = 0; i < ns; ++i) {
952 if (ELEV == INFINITY) {
954 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
956 ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) +
957 rnd((256 - HIGHMIN) / 2);
958 } else if ((c < nc &&
959 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
960 ((new_x(capx[c] + 2) == sectx[c][i] &&
961 capy[c] == secty[c][i])))
967 #define distance_to_land() distance_to_what(x, y, 1)
974 for (y = 0; y < WORLD_Y; ++y) {
975 for (x = y % 2; x < WORLD_X; x += 2) {
976 if (elev[x][y] == -INFINITY)
977 elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
982 /****************************************************************************
984 ****************************************************************************/
991 fert = LANDMIN - e + 40;
992 else if (e < FERT_MAX)
993 fert = (140 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
1004 oil = (LANDMIN - e) * 2 + rnd(2);
1005 else if (e <= OIL_MAX)
1006 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1016 if (e >= IRON_MIN && e < HIGHMIN)
1017 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1027 if (e >= GOLD_MIN) {
1029 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1031 gold = 100 - 20 * HIGHMIN / e;
1042 if (e >= URAN_MIN && e < HIGHMIN)
1043 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1050 add_resources(struct sctstr *sct)
1052 sct->sct_fertil = set_fert(sct->sct_elev);
1053 sct->sct_oil = set_oil(sct->sct_elev);
1054 sct->sct_min = set_iron(sct->sct_elev);
1055 sct->sct_gmin = set_gold(sct->sct_elev);
1056 sct->sct_uran = set_uran(sct->sct_elev);
1059 /****************************************************************************
1060 DESIGNATE THE SECTORS
1061 ****************************************************************************/
1066 register struct sctstr *sct;
1069 /* sct = §s[0][0]; */
1071 for (y = 0; y < YSIZE; y++) {
1072 for (x = 0; x < XSIZE; x++, sct++) {
1073 fl_sct_init(x * 2 + (y & 01), y, (s_char *)sct);
1074 total = elev[sct->sct_x][y];
1075 if (total < LANDMIN) {
1076 sct->sct_type = SCT_WATER;
1077 } else if (total < HILLMIN)
1078 sct->sct_type = SCT_RURAL;
1079 else if (total < PLATMIN)
1080 sct->sct_type = SCT_MOUNT;
1081 else if (total < HIGHMIN)
1082 sct->sct_type = SCT_RURAL;
1084 sct->sct_type = SCT_MOUNT;
1085 sct->sct_elev = total;
1086 sct->sct_newtype = sct->sct_type;
1092 for (c = 0; c < nc; ++c) {
1093 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_type = SCT_AIRPT;
1094 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_newtype = SCT_AIRPT;
1098 /****************************************************************************
1099 WRITE ALL THIS STUFF TO THE FILE
1100 ****************************************************************************/
1106 /* if ((n = write(the_file, sects, sizeof(sects))) < 0) { */
1107 if ((n = write(the_file, sectsbuf, YSIZE * XSIZE * sizeof(struct sctstr))) < 0) {
1108 perror(empfile[EF_SECTOR].file);
1111 if (n != (int)(YSIZE * XSIZE * sizeof(struct sctstr))) {
1112 printf("%s:partial write\n", empfile[EF_SECTOR].file);
1119 /****************************************************************************
1120 PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1121 ****************************************************************************/
1127 translate_continents();
1129 for (i = 0; i < WORLD_Y; ++i) {
1133 for (j = i % 2; j < WORLD_X; j += 2) {
1134 if (own[j][i] == -1)
1137 printf("%c ", map_symbol(j, i));
1143 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");
1146 /* Reorder the continents from top left to bottom right */
1148 translate_continents(void)
1150 int i, j, n = 0, k, gotit, c;
1151 int *trans, *trans_cont, *oldcapx, *oldcapy;
1153 trans = (int *)calloc(nc, sizeof(int));
1154 trans_cont = (int *)calloc(nc, sizeof(int));
1155 oldcapx = (int *)calloc(nc, sizeof(int));
1156 oldcapy = (int *)calloc(nc, sizeof(int));
1158 for (i = 0; i < WORLD_Y; ++i) {
1159 for (j = i % 2; j < WORLD_X; j += 2) {
1160 if (own[j][i] > -1 && own[j][i] < nc) {
1162 for (k = 0; k < n; ++k) {
1163 if (trans[k] == own[j][i])
1168 printf("fairland: BUG in translate continents! mail stevens@math.utoronto.ca\n");
1171 trans[n] = own[j][i];
1172 trans_cont[own[j][i]] = n;
1178 for (i = 0; i < WORLD_Y; ++i) {
1179 for (j = i % 2; j < WORLD_X; j += 2) {
1180 if (own[j][i] > -1 && own[j][i] < nc) {
1181 own[j][i] = trans_cont[own[j][i]];
1185 for (c = 0; c < nc; ++c) {
1186 oldcapx[c] = capx[c];
1187 oldcapy[c] = capy[c];
1189 for (c = 0; c < nc; ++c) {
1190 capx[c] = oldcapx[trans[c]];
1191 capy[c] = oldcapy[trans[c]];
1196 map_symbol(int x, int y)
1200 for (c = 0; c < nc; ++c)
1201 if ((x == capx[c] && y == capy[c])
1202 || (x == new_x(capx[c] + 2) && y == capy[c]))
1204 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
1205 || elev[x][y] >= HIGHMIN)
1207 return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
1210 /***************************************************************************
1211 WRITE A SCRIPT FOR PLACING CAPITALS
1212 ****************************************************************************/
1214 write_newcap_script(void)
1217 FILE *script = fopen(outfile, "w");
1220 printf("fairland: error, unable to write to %s.\n", outfile);
1224 for (c = 0; c < nc; ++c) {
1225 fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1);
1227 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1228 fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1230 fprintf(script, "add %d visitor visitor v i\n", c + 1);
1234 printf("\n\nA script for adding all the countries can be found in \"%s\".\n",
1240 qprint(const char *str)
1247 fl_sct_init(coord x, coord y, s_char *ptr)
1249 struct sctstr *sp = (struct sctstr *)ptr;
1251 sp->ef_type = EF_SECTOR;
1258 sp->sct_defense = 0;