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)
125 #define SRANDOM srandom
128 #define RANDOM random
130 #define rnd(x) (RANDOM() % (x))
132 int secs; /* number of sectors grown */
133 int ctot; /* total number of continents and islands grown */
134 int *isecs; /* array of how large each island is */
136 int nc, sc, di, sp, pm, ni, is, id; /* the 8 arguments to this program */
137 unsigned long rnd_seed; /* optional seed can be passed as an argument */
138 int *capx, *capy; /* location of the nc capitals */
139 int *mc, mcc; /* array and counter used for stability
140 check when perturbing */
141 int spike; /* are we spiking? */
142 int mind; /* the final distance between capitals that
144 int dirx[] = { -2, -1, 1, 2, 1, -1 }; /* gyujnb */
145 int diry[] = { 0, -1, -1, 0, 1, 1 };
147 int **own; /* owner of the sector. -1 means water */
148 int **elev; /* elevation of the sectors */
149 int **sectx, **secty; /* the sectors for each continent */
150 int **sectc; /* which sectors are on the coast? */
151 int *vector; /* used for measuring distances */
152 int *weight; /* used for placing mountains */
153 int *dsea, *dmoun; /* the dist to the ocean and mountain */
154 int the_file; /* the file we write everything to */
155 struct sctstr **sects;
156 struct sctstr *sectsbuf;
157 int fl_status; /* is anything wrong? */
158 #define STATUS_NO_ROOM (1) /* there was no room to grow */
159 #define NUMTRIES 10 /* keep trying to grow this many times */
161 const char *numletter =
162 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
164 static void parse_args(int argc, char *argv[]);
165 static int allocate_memory(void);
166 static void init(void);
167 static int drift(void);
168 static void grow_continents(void);
169 static void create_elevations(void);
170 static void write_sects(void);
171 static int write_file(void);
172 static void output(void);
173 static int write_newcap_script(void);
174 static int stable(void);
175 static void elevate_land(void);
176 static void elevate_sea(void);
177 static void translate_continents(void);
178 static int map_symbol(int x, int y);
179 static void fl_sct_init(coord x, coord y, s_char *ptr);
181 static void print_vars(void);
182 static void fl_move(int);
183 static void next_coast(int c, int x, int y, int *xp, int *yp);
184 static void grow_islands(void);
186 /****************************************************************************
188 ****************************************************************************/
191 main(int argc, char *argv[])
196 char *config_file = NULL;
200 rnd_seed = time(NULL);
202 rnd_seed += getpid();
204 while ((opt = getopt(argc, argv, "ae:ioqs:R:")) != EOF) {
210 DISTINCT_ISLANDS = 0;
213 config_file = optarg;
225 rnd_seed = strtoul(optarg, NULL, 10);
231 if (config_file == NULL) {
232 sprintf(tbuf, "%s/econfig", datadir);
235 emp_config(config_file);
238 parse_args(argc - optind, argv + optind);
240 parse_args(argc - 1, argv + 1);
242 if (allocate_memory() == -1)
249 printf("\ntry #%d (out of %d)...", i + 1, NUMTRIES);
250 qprint("\n\n #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
252 printf("seed is %lu\n", rnd_seed);
253 qprint("placing capitals...\n");
255 qprint("fairland: unstable drift -- try increasisg DRIFT_MAX\n");
256 qprint("growing continents...\n");
258 } while (fl_status && ++i < NUMTRIES);
260 fputs("ERROR: World not large enough to hold continents\n",
264 qprint("growing islands:");
266 qprint("\nelevating land...\n");
268 qprint("designating sectors...\n");
270 qprint("adding resources...\n");
272 qprint("writing to sectors file...\n");
273 if (write_file() == -1)
276 write_newcap_script();
278 printf("\t*** Resources have not been added ***\n");
287 puts("Creating a planet with:\n");
288 printf("%d continents\n", nc);
289 printf("continent size: %d\n", sc);
290 printf("number of islands: %d\n", ni);
291 printf("average size of islands: %d\n", is);
292 printf("spike: %d%%\n", sp);
293 printf("%d%% of land is mountain (each continent will have %d mountains)\n",
294 pm, (pm * sc) / 100);
295 printf("minimum distance between continents: %d\n", di);
296 printf("minimum distance from islands to continents: %d\n", id);
297 printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
305 for (i = 1; i * i < n * 10000; ++i) ;
306 return (i + 50) / 100;
309 /****************************************************************************
310 PARSE COMMAND LINE ARGUMENTS
311 ****************************************************************************/
314 parse_args(int argc, char *argv[])
316 if (argc < 2 || argc > 8) {
317 puts("fairland syntax:\n");
318 puts("fairland [-e config] [-aiqo] [-s script] [-R seed] <nc> <sc> [<ni>] [<is>] [<sp>] [<pm>] [<di>] [<id>]");
319 puts("-q = quiet, -o = no ore produced");
320 puts("-a = Airport marker for continents, -i = islands not distinct");
321 puts("-R = seed to use for random, -e = read config file");
322 printf("-s = name of script (default %s)\n",
324 puts("nc = number of continents [MANDATORY]");
325 puts("sc = continent size [MANDATORY]");
326 puts("ni = number of islands (default = nc)");
327 puts("is = average size of islands (default = sc/2)");
328 printf("sp = spike percentage: 0 = round, 100 = snake (default = %d)\n",
330 printf("pm = the percentage of land that is mountain (default = %d)\n",
332 printf("di = the minimum distance between continents (default = %d)\n",
334 printf("id = minimum distance from islands to continents (default = %d)\n",
340 puts("fairland: error -- number of continents must be > 0");
346 puts("fairland: error -- size of continents must be > 0");
374 pm = DEFAULT_MOUNTAIN;
381 di = DEFAULT_CONTDIST;
384 puts("fairland: error -- distance between continents must be >= 0");
387 if (di > WORLD_X / 2 || di > WORLD_Y / 2) {
388 puts("fairland: error -- distance between continents too large");
395 id = DEFAULT_ISLDIST;
397 puts("fairland: error -- distance from islands to continents must be >= 0");
400 if (id > WORLD_X || id > WORLD_Y) {
401 puts("fairland: error -- distance from islands to continents too large");
404 if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
405 puts("fairland: error -- world not big enough to fit continents.");
406 puts("arguments must satisfy:");
407 puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
412 /****************************************************************************
413 VARIABLE INITIALIZATION
414 ****************************************************************************/
417 allocate_memory(void)
423 open(empfile[EF_SECTOR].file, O_RDWR | O_CREAT | O_TRUNC, 0660);
426 open(empfile[EF_SECTOR].file,
427 O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0660);
430 perror(empfile[EF_SECTOR].file);
434 (struct sctstr *)calloc((YSIZE * XSIZE), sizeof(struct sctstr));
435 sects = (struct sctstr **)calloc(YSIZE, sizeof(struct sctstr *));
436 for (i = 0; i < YSIZE; i++)
437 sects[i] = §sbuf[XSIZE * i];
438 capx = (int *)calloc(nc, sizeof(int));
439 capy = (int *)calloc(nc, sizeof(int));
440 vector = (int *)calloc(WORLD_X + WORLD_Y, sizeof(int));
441 mc = (int *)calloc(STABLE_CYCLE, sizeof(int));
442 own = (int **)calloc(WORLD_X, sizeof(int *));
443 elev = (int **)calloc(WORLD_X, sizeof(int *));
444 for (i = 0; i < WORLD_X; ++i) {
445 own[i] = (int *)calloc(WORLD_Y, sizeof(int));
446 elev[i] = (int *)calloc(WORLD_Y, sizeof(int));
448 sectx = (int **)calloc(nc + ni, sizeof(int *));
449 secty = (int **)calloc(nc + ni, sizeof(int *));
450 sectc = (int **)calloc(nc + ni, sizeof(int *));
451 isecs = (int *)calloc(nc + ni, sizeof(int));
452 weight = (int *)calloc(max(sc, is * 2), sizeof(int));
453 dsea = (int *)calloc(max(sc, is * 2), sizeof(int));
454 dmoun = (int *)calloc(max(sc, is * 2), sizeof(int));
455 for (i = 0; i < nc; ++i) {
456 sectx[i] = (int *)calloc(sc, sizeof(int));
457 secty[i] = (int *)calloc(sc, sizeof(int));
458 sectc[i] = (int *)calloc(sc, sizeof(int));
460 for (i = nc; i < nc + ni; ++i) {
461 sectx[i] = (int *)calloc(is * 2, sizeof(int));
462 secty[i] = (int *)calloc(is * 2, sizeof(int));
463 sectc[i] = (int *)calloc(is * 2, sizeof(int));
472 int i, j, xx = 0, yy = 0;
477 for (i = 0; i < WORLD_X; ++i) {
478 for (j = 0; j < WORLD_Y; ++j) {
480 elev[i][j] = -INFINITY;
484 for (i = 0; i < nc; ++i, xx += 2) {
489 puts("fairland error: world not big enough for all the continents.\n");
496 for (i = 0; i < STABLE_CYCLE; ++i)
500 /****************************************************************************
501 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
502 ****************************************************************************/
504 /* How isolated is capital j?
507 iso(int j, int newx, int newy)
509 int i, md, d = WORLD_X + WORLD_Y;
511 for (i = 0; i < nc; ++i) {
514 md = mapdist(capx[i], capy[i], newx, newy);
522 /* Drift all the capitals
529 for (turns = 0; turns < DRIFT_MAX; ++turns) {
530 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
532 for (i = 0; i < nc; ++i)
538 /* Check to see if we have stabilized--can we stop drifting the capitals?
544 int i, isod, d = 0, stab = 1;
546 for (i = 0; i < nc; ++i) {
547 isod = iso(i, capx[i], capy[i]);
551 for (i = 0; i < STABLE_CYCLE; ++i)
555 mcc = (mcc + 1) % STABLE_CYCLE;
559 /* This routine does the actual drifting
565 int i, n, newx, newy;
567 for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
568 newx = new_x(capx[j] + dirx[i]);
569 newy = new_y(capy[j] + diry[i]);
570 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
578 /****************************************************************************
580 ****************************************************************************/
582 /* Look for a coastal sector of continent c
590 for (i = 0; i < secs; ++i) {
592 for (j = 0; j < 6; ++j)
593 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
598 /* Used for measuring distances
610 for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
613 return i > 1 || vector[0] > 0;
616 /* Test to see if we're allowed to grow there: the arguments di and id
619 try_to_grow(int c, int newx, int newy, int d)
623 for (i = 1; i <= d; ++i) {
624 for (j = 0; j < i; ++j)
629 for (j = 0; j < i; ++j) {
630 px = new_x(px + dirx[vector[j]]);
631 py = new_y(py + diry[vector[j]]);
633 if (own[px][py] != -1 &&
635 (DISTINCT_ISLANDS || own[px][py] < nc))
637 } while (next_vector(i));
639 sectx[c][secs] = newx;
640 secty[c][secs] = newy;
645 /* Move along the coast in a clockwise direction.
649 next_coast(int c, int x, int y, int *xp, int *yp)
651 int i, nx, ny, wat = 0;
659 for (i = 0; i < 12; ++i) {
660 nx = new_x(x + dirx[i % 6]);
661 ny = new_y(y + diry[i % 6]);
662 if (own[nx][ny] == -1)
664 if (wat && own[nx][ny] == c) {
672 /* Choose a sector to grow from
684 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
689 } while (i != starti);
691 printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n",
700 /* Grow continent c by 1 sector
704 grow_one_sector(int c)
706 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
708 spike = rnd(100) < sp;
709 if ((try1 = new_try(c)) == -1)
711 x = sx = sectx[c][try1];
712 y = sy = secty[c][try1];
717 for (i = rnd(6), n = 0; n < 12 && !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 &&
722 (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
723 own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
724 if (try_to_grow(c, newx, newy, c < nc ? di : id))
728 for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
729 newx = new_x(x + dirx[i]);
730 newy = new_y(y + diry[i]);
731 if (own[newx][newy] == -1)
732 if (try_to_grow(c, newx, newy, c < nc ? di : id))
735 next_coast(c, x, y, &x, &y);
737 } while (!done && coast_search < COAST_SEARCH_MAX &&
738 (secs == 1 || x != sx || y != sy));
739 if (!done && c < nc) {
741 printf("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) {
770 if (fl_status && !quiet)
771 printf("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));
826 printf(" %d(%d)", c - nc + 1, secs);
832 /****************************************************************************
834 ****************************************************************************/
836 create_elevations(void)
842 /* Generic function for finding the distance to the closest sea, land, or
846 distance_to_what(int x, int y, int flag)
850 for (d = 1; d < 5; ++d) {
851 for (j = 0; j < d; ++j)
856 for (j = 0; j < d; ++j) {
857 px = new_x(px + dirx[vector[j]]);
858 py = new_y(py + diry[vector[j]]);
861 case 0: /* distance to sea */
862 if (own[px][py] == -1)
865 case 1: /* distance to land */
866 if (own[px][py] != -1)
869 case 2: /* distance to mountain */
870 if (elev[px][py] == INFINITY)
874 } while (next_vector(d));
879 #define ELEV elev[sectx[c][i]][secty[c][i]]
880 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
881 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
883 /* Decide where the mountains go
888 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
891 for (c = 0; c < ctot; ++c) {
893 ns = (c < nc) ? sc : isecs[c];
894 nm = (pm * ns) / 100;
896 /* Place the mountains */
898 for (i = 0; i < ns; ++i) {
899 dsea[i] = distance_to_sea();
900 weight[i] = (total += (dsea[i] * dsea[i]));
903 for (k = nm, mountain_search = 0;
904 k && mountain_search < MOUNTAIN_SEARCH_MAX;
907 for (i = 0; i < ns; ++i)
908 if (r < weight[i] && ELEV == -INFINITY &&
910 ((!(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]))))) {
920 /* Elevate land that is not mountain and not capital */
922 for (i = 0; i < ns; ++i)
923 dmoun[i] = distance_to_mountain();
924 dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
925 (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
927 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
930 for (i = 0; i < ns; ++i) {
931 if (ELEV != INFINITY &&
932 (c >= nc || ((!(capx[c] == sectx[c][i] &&
933 capy[c] == secty[c][i])) &&
934 (!(new_x(capx[c] + 2) == sectx[c][i] &&
935 capy[c] == secty[c][i]))))) {
936 h = 3 * (5 - dmoun[i]) + dsea[i];
946 if (newk >= HILLMIN && newk < PLATMIN)
950 elev[sectx[c][where]][secty[c][where]] = newk;
951 dsea[where] = -INFINITY;
952 dmoun[where] = INFINITY;
955 /* Elevate the mountains and capitals */
957 for (i = 0; i < ns; ++i) {
958 if (ELEV == INFINITY) {
960 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
962 ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) +
963 rnd((256 - HIGHMIN) / 2);
964 } else if ((c < nc &&
965 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
966 ((new_x(capx[c] + 2) == sectx[c][i] &&
967 capy[c] == secty[c][i])))
973 #define distance_to_land() distance_to_what(x, y, 1)
980 for (y = 0; y < WORLD_Y; ++y) {
981 for (x = y % 2; x < WORLD_X; x += 2) {
982 if (elev[x][y] == -INFINITY)
983 elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
988 /****************************************************************************
990 ****************************************************************************/
997 fert = LANDMIN - e + 40;
998 else if (e < FERT_MAX)
999 fert = (140 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
1010 oil = (LANDMIN - e) * 2 + rnd(2);
1011 else if (e <= OIL_MAX)
1012 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1022 if (e >= IRON_MIN && e < HIGHMIN)
1023 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1033 if (e >= GOLD_MIN) {
1035 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1037 gold = 100 - 20 * HIGHMIN / e;
1048 if (e >= URAN_MIN && e < HIGHMIN)
1049 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1056 add_resources(struct sctstr *sct)
1058 sct->sct_fertil = set_fert(sct->sct_elev);
1059 sct->sct_oil = set_oil(sct->sct_elev);
1060 sct->sct_min = set_iron(sct->sct_elev);
1061 sct->sct_gmin = set_gold(sct->sct_elev);
1062 sct->sct_uran = set_uran(sct->sct_elev);
1065 /****************************************************************************
1066 DESIGNATE THE SECTORS
1067 ****************************************************************************/
1072 register struct sctstr *sct;
1075 /* sct = §s[0][0]; */
1077 for (y = 0; y < YSIZE; y++) {
1078 for (x = 0; x < XSIZE; x++, sct++) {
1079 fl_sct_init(x * 2 + (y & 01), y, (s_char *)sct);
1080 total = elev[sct->sct_x][y];
1081 if (total < LANDMIN) {
1082 sct->sct_type = SCT_WATER;
1083 } else if (total < HILLMIN)
1084 sct->sct_type = SCT_RURAL;
1085 else if (total < PLATMIN)
1086 sct->sct_type = SCT_MOUNT;
1087 else if (total < HIGHMIN)
1088 sct->sct_type = SCT_RURAL;
1090 sct->sct_type = SCT_MOUNT;
1091 sct->sct_elev = total;
1092 sct->sct_newtype = sct->sct_type;
1098 for (c = 0; c < nc; ++c) {
1099 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_type = SCT_AIRPT;
1100 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_newtype = SCT_AIRPT;
1104 /****************************************************************************
1105 WRITE ALL THIS STUFF TO THE FILE
1106 ****************************************************************************/
1112 /* if ((n = write(the_file, sects, sizeof(sects))) < 0) { */
1113 if ((n = write(the_file, sectsbuf, YSIZE * XSIZE * sizeof(struct sctstr))) < 0) {
1114 perror(empfile[EF_SECTOR].file);
1117 if (n != (int)(YSIZE * XSIZE * sizeof(struct sctstr))) {
1118 printf("%s:partial write\n", empfile[EF_SECTOR].file);
1125 /****************************************************************************
1126 PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1127 ****************************************************************************/
1133 translate_continents();
1135 for (i = 0; i < WORLD_Y; ++i) {
1139 for (j = i % 2; j < WORLD_X; j += 2) {
1140 if (own[j][i] == -1)
1143 printf("%c ", map_symbol(j, i));
1149 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");
1152 /* Reorder the continents from top left to bottom right */
1154 translate_continents(void)
1156 int i, j, n = 0, k, gotit, c;
1157 int *trans, *trans_cont, *oldcapx, *oldcapy;
1159 trans = (int *)calloc(nc, sizeof(int));
1160 trans_cont = (int *)calloc(nc, sizeof(int));
1161 oldcapx = (int *)calloc(nc, sizeof(int));
1162 oldcapy = (int *)calloc(nc, sizeof(int));
1164 for (i = 0; i < WORLD_Y; ++i) {
1165 for (j = i % 2; j < WORLD_X; j += 2) {
1166 if (own[j][i] > -1 && own[j][i] < nc) {
1168 for (k = 0; k < n; ++k) {
1169 if (trans[k] == own[j][i])
1174 printf("fairland: BUG in translate continents! mail stevens@math.utoronto.ca\n");
1177 trans[n] = own[j][i];
1178 trans_cont[own[j][i]] = n;
1184 for (i = 0; i < WORLD_Y; ++i) {
1185 for (j = i % 2; j < WORLD_X; j += 2) {
1186 if (own[j][i] > -1 && own[j][i] < nc) {
1187 own[j][i] = trans_cont[own[j][i]];
1191 for (c = 0; c < nc; ++c) {
1192 oldcapx[c] = capx[c];
1193 oldcapy[c] = capy[c];
1195 for (c = 0; c < nc; ++c) {
1196 capx[c] = oldcapx[trans[c]];
1197 capy[c] = oldcapy[trans[c]];
1202 map_symbol(int x, int y)
1206 for (c = 0; c < nc; ++c)
1207 if ((x == capx[c] && y == capy[c])
1208 || (x == new_x(capx[c] + 2) && y == capy[c]))
1210 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
1211 || elev[x][y] >= HIGHMIN)
1213 return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
1216 /***************************************************************************
1217 WRITE A SCRIPT FOR PLACING CAPITALS
1218 ****************************************************************************/
1220 write_newcap_script(void)
1223 FILE *script = fopen(outfile, "w");
1226 printf("fairland: error, unable to write to %s.\n", outfile);
1230 for (c = 0; c < nc; ++c) {
1231 fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1);
1233 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1234 fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1236 fprintf(script, "add %d visitor visitor v i\n", c + 1);
1240 printf("\n\nA script for adding all the countries can be found in \"%s\".\n",
1246 qprint(const char *str)
1253 fl_sct_init(coord x, coord y, s_char *ptr)
1255 struct sctstr *sp = (struct sctstr *)ptr;
1257 sp->ef_type = EF_SECTOR;
1264 sp->sct_defense = 0;