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 */
82 #include "prototypes.h"
84 /* do not change these 4 defines */
85 #define LANDMIN 1 /* plate altitude for normal land */
86 #define HILLMIN 34 /* plate altitude for hills */
87 #define PLATMIN 36 /* plate altitude for plateau */
88 #define HIGHMIN 98 /* plate altitude for mountains */
90 static void qprint _PROTO((const char *str));
92 static const char *outfile = "newcap_script";
93 /* mark the continents with a * so you can tell them
94 from the islands 1 = mark, 0 = don't mark. */
95 static int AIRPORT_MARKER = 0;
97 /* don't let the islands crash into each other.
98 1 = don't merge, 0 = merge. */
99 static int DISTINCT_ISLANDS = 1;
101 #define XSIZE ((WORLD_X) / 2) /* basically world x-y size */
102 #define YSIZE (WORLD_Y)
103 #define STABLE_CYCLE 4 /* stability required for perterbed capitals */
104 #define INFINITY 999 /* a number which means "BIG" */
106 /* these defines prevent infinite loops:
109 #define COAST_SEARCH_MAX 200 /* how many times do we look for a coast sector
110 when growing continents and islands */
111 #define DRIFT_BEFORE_CHECK ((WORLD_X + WORLD_Y)/2)
112 #define DRIFT_MAX ((WORLD_X + WORLD_Y)*2)
113 #define MOUNTAIN_SEARCH_MAX 1000 /* how long do we try to place mountains */
118 #define new_x(newx) (((newx) + WORLD_X) % WORLD_X)
119 #define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y)
121 #define max(a,b) (a>b?a:b)
123 #define rnd(x) (random() % (x))
125 int secs; /* number of sectors grown */
126 int ctot; /* total number of continents and islands grown */
127 int *isecs; /* array of how large each island is */
129 int nc, sc, di, sp, pm, ni, is, id; /* the 8 arguments to this program */
130 int *capx, *capy; /* location of the nc capitals */
131 int *mc, mcc; /* array and counter used for stability
132 check when perturbing */
133 int spike; /* are we spiking? */
134 int mind; /* the final distance between capitals that
136 int dirx[] = { -2, -1, 1, 2, 1, -1 }; /* gyujnb */
137 int diry[] = { 0, -1, -1, 0, 1, 1 };
139 int **own; /* owner of the sector. -1 means water */
140 int **elev; /* elevation of the sectors */
141 int **sectx, **secty; /* the sectors for each continent */
142 int **sectc; /* which sectors are on the coast? */
143 int *vector; /* used for measuring distances */
144 int *weight; /* used for placing mountains */
145 int *dsea, *dmoun; /* the dist to the ocean and mountain */
146 int the_file; /* the file we write everything to */
147 struct sctstr **sects;
148 struct sctstr *sectsbuf;
149 int fl_status; /* is anything wrong? */
150 #define STATUS_NO_ROOM (1) /* there was no room to grow */
151 #define NUMTRIES 10 /* keep trying to grow this many times */
153 const char *numletter =
154 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
156 void parse_args(int argc, char *argv[]);
157 int allocate_memory(void);
160 void grow_continents(void);
161 void create_elevations(void);
162 void write_sects(void);
163 int write_file(void);
165 int write_newcap_script(void);
167 void elevate_land(void);
168 void elevate_sea(void);
169 void translate_continents(void);
170 int map_symbol(int x, int y);
171 static void fl_sct_init(coord x, coord y, s_char *ptr);
178 /****************************************************************************
180 ****************************************************************************/
183 main(int argc, char *argv[])
188 extern s_char *datadir;
189 char *config_file = NULL;
194 while ((opt = getopt(argc, argv, "ae:ioqs:")) != EOF) {
200 DISTINCT_ISLANDS = 0;
203 config_file = optarg;
217 if (config_file == NULL) {
218 sprintf(tbuf, "%s/econfig", datadir);
221 emp_config(config_file);
224 parse_args(argc - optind, argv + optind);
226 parse_args(argc - 1, argv + 1);
228 if (allocate_memory() == -1)
235 printf("\ntry #%d (out of %d)...", i + 1, NUMTRIES);
237 ("\n\n #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
238 qprint("placing capitals...\n");
241 ("fairland: unstable drift -- try increasisg DRIFT_MAX\n");
242 qprint("growing continents...\n");
244 } while (fl_status && ++i < NUMTRIES);
246 fputs("ERROR: World not large enough to hold continents\n",
250 qprint("growing islands:");
252 qprint("\nelevating land...\n");
254 qprint("designating sectors...\n");
256 qprint("adding resources...\n");
258 qprint("writing to sectors file...\n");
259 if (write_file() == -1)
262 write_newcap_script();
271 puts("Creating a planet with:\n");
272 printf("%d continents\n", nc);
273 printf("continent size: %d\n", sc);
274 printf("number of islands: %d\n", ni);
275 printf("average size of islands: %d\n", is);
276 printf("spike: %d%%\n", sp);
278 ("%d%% of land is mountain (each continent will have %d mountains)\n",
279 pm, (pm * sc) / 100);
280 printf("minimum distance between continents: %d\n", di);
281 printf("minimum distance from islands to continents: %d\n", id);
282 printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
291 for (i = 1; i * i < n * 10000; ++i) ;
292 return (i + 50) / 100;
295 /****************************************************************************
296 PARSE COMMAND LINE ARGUMENTS
297 ****************************************************************************/
300 parse_args(int argc, char *argv[])
302 if (argc < 2 || argc > 8) {
303 puts("fairland syntax:\n");
304 puts("fairland [-e config] [-aiqo] [-s script] <nc> <sc> [<ni>] [<is>] [<sp>] [<pm>] [<di>] [<id>]");
305 puts("-q = quiet, -o = no ore produced");
306 puts("-a = Airport marker for continents, -i = islands not distinct");
307 printf("-e = read config file, -s = name of script (default %s)\n",
309 puts("nc = number of continents [MANDATORY]");
310 puts("sc = continent size [MANDATORY]");
311 puts("ni = number of islands (default = nc)");
312 puts("is = average size of islands (default = sc/2)");
314 ("sp = spike percentage: 0 = round, 100 = snake (default = %d)\n",
317 ("pm = the percentage of land that is mountain (default = %d)\n",
320 ("di = the minimum distance between continents (default = %d)\n",
323 ("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)
413 open(empfile[EF_SECTOR].file, O_RDWR | O_CREAT | O_TRUNC, 0660);
416 open(empfile[EF_SECTOR].file,
417 O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0660);
420 perror(empfile[EF_SECTOR].file);
424 (struct sctstr *)calloc((YSIZE * XSIZE), sizeof(struct sctstr));
425 sects = (struct sctstr **)calloc(YSIZE, sizeof(struct sctstr *));
426 for (i = 0; i < YSIZE; i++)
427 sects[i] = §sbuf[XSIZE * i];
430 srandom(now + getpid());
434 capx = (int *)calloc(nc, sizeof(int));
435 capy = (int *)calloc(nc, sizeof(int));
436 vector = (int *)calloc(WORLD_X + WORLD_Y, sizeof(int));
437 mc = (int *)calloc(STABLE_CYCLE, sizeof(int));
438 own = (int **)calloc(WORLD_X, sizeof(int *));
439 elev = (int **)calloc(WORLD_X, sizeof(int *));
440 for (i = 0; i < WORLD_X; ++i) {
441 own[i] = (int *)calloc(WORLD_Y, sizeof(int));
442 elev[i] = (int *)calloc(WORLD_Y, sizeof(int));
444 sectx = (int **)calloc(nc + ni, sizeof(int *));
445 secty = (int **)calloc(nc + ni, sizeof(int *));
446 sectc = (int **)calloc(nc + ni, sizeof(int *));
447 isecs = (int *)calloc(nc + ni, sizeof(int));
448 weight = (int *)calloc(max(sc, is * 2), sizeof(int));
449 dsea = (int *)calloc(max(sc, is * 2), sizeof(int));
450 dmoun = (int *)calloc(max(sc, is * 2), sizeof(int));
451 for (i = 0; i < nc; ++i) {
452 sectx[i] = (int *)calloc(sc, sizeof(int));
453 secty[i] = (int *)calloc(sc, sizeof(int));
454 sectc[i] = (int *)calloc(sc, sizeof(int));
456 for (i = nc; i < nc + ni; ++i) {
457 sectx[i] = (int *)calloc(is * 2, sizeof(int));
458 secty[i] = (int *)calloc(is * 2, sizeof(int));
459 sectc[i] = (int *)calloc(is * 2, sizeof(int));
468 int i, j, xx = 0, yy = 0;
473 for (i = 0; i < WORLD_X; ++i) {
474 for (j = 0; j < WORLD_Y; ++j) {
476 elev[i][j] = -INFINITY;
480 for (i = 0; i < nc; ++i, xx += 2) {
485 puts("fairland error: world not big enough for all the continents.\n");
492 for (i = 0; i < STABLE_CYCLE; ++i)
496 /****************************************************************************
497 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
498 ****************************************************************************/
500 /* How isolated is capital j?
506 int i, md, d = WORLD_X + WORLD_Y;
508 for (i = 0; i < nc; ++i) {
511 md = mapdist(capx[i], capy[i], newx, newy);
519 /* Drift all the capitals
526 for (turns = 0; turns < DRIFT_MAX; ++turns) {
527 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
529 for (i = 0; i < nc; ++i)
535 /* Check to see if we have stabilized--can we stop drifting the capitals?
541 int i, isod, d = 0, stab = 1;
543 for (i = 0; i < nc; ++i) {
544 isod = iso(i, capx[i], capy[i]);
548 for (i = 0; i < STABLE_CYCLE; ++i)
552 mcc = (mcc + 1) % STABLE_CYCLE;
556 /* This routine does the actual drifting
563 int i, n, newx, newy;
565 for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
566 newx = new_x(capx[j] + dirx[i]);
567 newy = new_y(capy[j] + diry[i]);
568 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
576 /****************************************************************************
578 ****************************************************************************/
580 /* Look for a coastal sector of continent c
589 for (i = 0; i < secs; ++i) {
591 for (j = 0; j < 6; ++j)
592 if (own[new_x(sectx[c][i] + dirx[j])]
593 [new_y(secty[c][i] + diry[j])] == -1)
598 /* 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(c, newx, newy, d)
621 int c, newx, newy, d;
625 for (i = 1; i <= d; ++i) {
626 for (j = 0; j < i; ++j)
631 for (j = 0; j < i; ++j) {
632 px = new_x(px + dirx[vector[j]]);
633 py = new_y(py + diry[vector[j]]);
635 if (own[px][py] != -1 &&
636 own[px][py] != c && (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(c, x, y, xp, yp)
651 int c, x, y, *xp, *yp;
653 int i, nx, ny, wat = 0;
661 for (i = 0; i < 12; ++i) {
662 nx = new_x(x + dirx[i % 6]);
663 ny = new_y(y + diry[i % 6]);
664 if (own[nx][ny] == -1)
666 if (wat && own[nx][ny] == c) {
674 /* Choose a sector to grow from
686 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
691 } while (i != starti);
694 ("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n",
703 /* Grow continent c by 1 sector
710 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
712 spike = rnd(100) < sp;
713 if ((try1 = new_try(c)) == -1)
715 x = sx = sectx[c][try1];
716 y = sy = secty[c][try1];
721 for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
722 newx = new_x(x + dirx[i]);
723 newy = new_y(y + diry[i]);
724 if (own[newx][newy] == -1 &&
726 (own[new_x(x + dirx[(i + 5) % 6])]
727 [new_y(y + diry[(i + 5) % 6])] == -1
729 own[new_x(x + dirx[(i + 1) % 6])][new_y
734 if (try_to_grow(c, newx, newy, c < nc ? di : id))
738 for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
739 newx = new_x(x + dirx[i]);
740 newy = new_y(y + diry[i]);
741 if (own[newx][newy] == -1)
742 if (try_to_grow(c, newx, newy, c < nc ? di : id))
745 next_coast(c, x, y, &x, &y);
747 } while (!done && coast_search < COAST_SEARCH_MAX &&
748 (secs == 1 || x != sx || y != sy));
749 if (!done && c < nc) {
752 ("fairland: error -- continent %c had no room to grow!\n",
754 fl_status |= STATUS_NO_ROOM;
759 /* Grow all the continents
762 grow_continents(void)
766 for (c = 0; c < nc; ++c) {
767 sectx[c][0] = capx[c];
768 secty[c][0] = capy[c];
769 own[sectx[c][0]][secty[c][0]] = c;
770 sectx[c][1] = new_x(capx[c] + 2);
771 secty[c][1] = capy[c];
772 own[sectx[c][1]][secty[c][1]] = c;
775 for (secs = 2; secs < sc && !fl_status; ++secs) {
776 for (c = 0; c < nc; ++c) {
781 if (fl_status && !quiet)
782 printf("Only managed to grow %d out of %d sectors.\n", secs, sc);
786 /****************************************************************************
788 ****************************************************************************/
790 /* Choose a place to start growing an island from
793 place_island(c, xp, yp)
797 int ssy = rnd(WORLD_Y);
798 int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2);
800 if (ssx > WORLD_X - 2)
801 ssx = new_x(ssx + 2);
802 for (d = di + id; d >= id; --d) {
806 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
807 if (*xp >= WORLD_X) {
808 *yp = new_y(*yp + 1);
810 if (*xp == sx && *yp == sy)
813 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
820 /* Grow all the islands
828 for (c = nc; c < nc + ni; ++c) {
830 if (!place_island(c, &x, &y))
832 isiz = 1 + rnd(2 * is - 1);
836 } while (secs < isiz && grow_one_sector(c));
838 printf(" %d(%d)", c - nc + 1, secs);
844 /****************************************************************************
846 ****************************************************************************/
848 create_elevations(void)
854 /* Generic function for finding the distance to the closest sea, land, or
858 distance_to_what(x, y, flag)
863 for (d = 1; d < 5; ++d) {
864 for (j = 0; j < d; ++j)
869 for (j = 0; j < d; ++j) {
870 px = new_x(px + dirx[vector[j]]);
871 py = new_y(py + diry[vector[j]]);
874 case 0: /* distance to sea */
875 if (own[px][py] == -1)
878 case 1: /* distance to land */
879 if (own[px][py] != -1)
882 case 2: /* distance to mountain */
883 if (elev[px][py] == INFINITY)
887 } while (next_vector(d));
892 #define ELEV elev[sectx[c][i]][secty[c][i]]
893 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
894 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
896 /* Decide where the mountains go
901 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
904 for (c = 0; c < ctot; ++c) {
906 ns = (c < nc) ? sc : isecs[c];
907 nm = (pm * ns) / 100;
909 /* Place the mountains */
911 for (i = 0; i < ns; ++i) {
912 dsea[i] = distance_to_sea();
913 weight[i] = (total += (dsea[i] * dsea[i]));
916 for (k = nm, mountain_search = 0;
917 k && mountain_search < MOUNTAIN_SEARCH_MAX;
920 for (i = 0; i < ns; ++i)
921 if (r < weight[i] && ELEV == -INFINITY && (c >= nc ||
943 /* Elevate land that is not mountain and not capital */
945 for (i = 0; i < ns; ++i)
946 dmoun[i] = distance_to_mountain();
947 dk = (ns - nm - ((c < nc) ? 3 : 1) >
948 0) ? (100 * (HIGHMIN - LANDMIN)) / (ns - nm -
950 nc) ? 3 : 1)) : 100 *
952 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
955 for (i = 0; i < ns; ++i) {
956 if (ELEV != INFINITY && (c >= nc ||
957 ((!(capx[c] == sectx[c][i]
958 && capy[c] == secty[c][i]))
960 (!(new_x(capx[c] + 2) ==
964 h = 3 * (5 - dmoun[i]) + dsea[i];
974 if (newk >= HILLMIN && newk < PLATMIN)
978 elev[sectx[c][where]][secty[c][where]] = newk;
979 dsea[where] = -INFINITY;
980 dmoun[where] = INFINITY;
983 /* Elevate the mountains and capitals */
985 for (i = 0; i < ns; ++i) {
986 if (ELEV == INFINITY) {
988 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
991 HIGHMIN + rnd((256 - HIGHMIN) / 2) +
992 rnd((256 - HIGHMIN) / 2);
996 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i])))
998 ((new_x(capx[c] + 2) == sectx[c][i]
999 && capy[c] == secty[c][i])))
1005 #define distance_to_land() distance_to_what(x, y, 1)
1012 for (y = 0; y < WORLD_Y; ++y) {
1013 for (x = y % 2; x < WORLD_X; x += 2) {
1014 if (elev[x][y] == -INFINITY)
1015 elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
1020 /****************************************************************************
1022 ****************************************************************************/
1030 fert = LANDMIN - e + 40;
1031 else if (e < FERT_MAX)
1032 fert = (140 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
1044 oil = (LANDMIN - e) * 2 + rnd(2);
1045 else if (e <= OIL_MAX)
1046 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1057 if (e >= IRON_MIN && e < HIGHMIN)
1058 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1069 if (e >= GOLD_MIN) {
1071 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1073 gold = 100 - 20 * HIGHMIN / e;
1085 if (e >= URAN_MIN && e < HIGHMIN)
1086 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1096 sct->sct_fertil = set_fert(sct->sct_elev);
1097 sct->sct_oil = set_oil(sct->sct_elev);
1098 sct->sct_min = set_iron(sct->sct_elev);
1099 sct->sct_gmin = set_gold(sct->sct_elev);
1100 sct->sct_uran = set_uran(sct->sct_elev);
1103 /****************************************************************************
1104 DESIGNATE THE SECTORS
1105 ****************************************************************************/
1110 register struct sctstr *sct;
1113 /* sct = §s[0][0]; */
1115 for (y = 0; y < YSIZE; y++) {
1116 for (x = 0; x < XSIZE; x++, sct++) {
1117 fl_sct_init(x * 2 + (y & 01), y, (s_char *)sct);
1118 total = elev[sct->sct_x][y];
1119 if (total < LANDMIN) {
1120 sct->sct_type = SCT_WATER;
1121 } else if (total < HILLMIN)
1122 sct->sct_type = SCT_RURAL;
1123 else if (total < PLATMIN)
1124 sct->sct_type = SCT_MOUNT;
1125 else if (total < HIGHMIN)
1126 sct->sct_type = SCT_RURAL;
1128 sct->sct_type = SCT_MOUNT;
1129 sct->sct_elev = total;
1130 sct->sct_newtype = sct->sct_type;
1136 for (c = 0; c < nc; ++c) {
1137 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_type = SCT_AIRPT;
1138 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_newtype =
1143 /****************************************************************************
1144 WRITE ALL THIS STUFF TO THE FILE
1145 ****************************************************************************/
1151 /* if ((n = write(the_file, sects, sizeof(sects))) < 0) { */
1153 write(the_file, sectsbuf,
1154 YSIZE * XSIZE * sizeof(struct sctstr))) < 0) {
1155 perror(empfile[EF_SECTOR].file);
1158 if (n != (int)(YSIZE * XSIZE * sizeof(struct sctstr))) {
1159 printf("%s:partial write\n", empfile[EF_SECTOR].file);
1166 /****************************************************************************
1167 PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1168 ****************************************************************************/
1174 translate_continents();
1176 for (i = 0; i < WORLD_Y; ++i) {
1180 for (j = i % 2; j < WORLD_X; j += 2) {
1181 if (own[j][i] == -1)
1184 printf("%c ", map_symbol(j, i));
1191 ("\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");
1194 /* Reorder the continents from top left to bottom right */
1196 translate_continents(void)
1198 int i, j, n = 0, k, gotit, c;
1199 int *trans, *trans_cont, *oldcapx, *oldcapy;
1201 trans = (int *)calloc(nc, sizeof(int));
1202 trans_cont = (int *)calloc(nc, sizeof(int));
1203 oldcapx = (int *)calloc(nc, sizeof(int));
1204 oldcapy = (int *)calloc(nc, sizeof(int));
1206 for (i = 0; i < WORLD_Y; ++i) {
1207 for (j = i % 2; j < WORLD_X; j += 2) {
1208 if (own[j][i] > -1 && own[j][i] < nc) {
1210 for (k = 0; k < n; ++k) {
1211 if (trans[k] == own[j][i])
1217 ("fairland: BUG in translate continents! mail stevens@math.utoronto.ca\n");
1220 trans[n] = own[j][i];
1221 trans_cont[own[j][i]] = n;
1227 for (i = 0; i < WORLD_Y; ++i) {
1228 for (j = i % 2; j < WORLD_X; j += 2) {
1229 if (own[j][i] > -1 && own[j][i] < nc) {
1230 own[j][i] = trans_cont[own[j][i]];
1234 for (c = 0; c < nc; ++c) {
1235 oldcapx[c] = capx[c];
1236 oldcapy[c] = capy[c];
1238 for (c = 0; c < nc; ++c) {
1239 capx[c] = oldcapx[trans[c]];
1240 capy[c] = oldcapy[trans[c]];
1245 map_symbol(int x, int y)
1249 for (c = 0; c < nc; ++c)
1250 if ((x == capx[c] && y == capy[c])
1251 || (x == new_x(capx[c] + 2) && y == capy[c]))
1253 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
1254 || elev[x][y] >= HIGHMIN)
1256 return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
1259 /***************************************************************************
1260 WRITE A SCRIPT FOR PLACING CAPITALS
1261 ****************************************************************************/
1263 write_newcap_script(void)
1266 FILE *script = fopen(outfile, "w");
1269 printf("fairland: error, unable to write to %s.\n", outfile);
1273 for (c = 0; c < nc; ++c) {
1274 fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1);
1276 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1277 fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1279 fprintf(script, "add %d visitor visitor v i\n", c + 1);
1284 ("\n\nA script for adding all the countries can be found in \"%s\".\n",
1286 if (ORE && quiet == 0)
1288 ("\t***IMPORTANT: Resources have already been added***\n\tYou do NOT need to run the ore program.\n");
1301 fl_sct_init(coord x, coord y, s_char *ptr)
1303 struct sctstr *sp = (struct sctstr *)ptr;
1305 sp->ef_type = EF_SECTOR;
1312 sp->sct_defense = 0;