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(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 static void parse_args(int argc, char *argv[]);
157 static int allocate_memory(void);
158 static void init(void);
159 static int drift(void);
160 static void grow_continents(void);
161 static void create_elevations(void);
162 static void write_sects(void);
163 static int write_file(void);
164 static void output(void);
165 static int write_newcap_script(void);
166 static int stable(void);
167 static void elevate_land(void);
168 static void elevate_sea(void);
169 static void translate_continents(void);
170 static int map_symbol(int x, int y);
171 static void fl_sct_init(coord x, coord y, s_char *ptr);
173 static void print_vars(void);
174 static void fl_move(int);
175 static void next_coast(int c, int x, int y, int *xp, int *yp);
176 static void grow_islands(void);
178 /****************************************************************************
180 ****************************************************************************/
183 main(int argc, char *argv[])
188 char *config_file = NULL;
193 while ((opt = getopt(argc, argv, "ae:ioqs:")) != EOF) {
199 DISTINCT_ISLANDS = 0;
202 config_file = optarg;
216 if (config_file == NULL) {
217 sprintf(tbuf, "%s/econfig", datadir);
220 emp_config(config_file);
223 parse_args(argc - optind, argv + optind);
225 parse_args(argc - 1, argv + 1);
227 if (allocate_memory() == -1)
234 printf("\ntry #%d (out of %d)...", i + 1, NUMTRIES);
235 qprint("\n\n #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
236 qprint("placing capitals...\n");
238 qprint("fairland: unstable drift -- try increasisg DRIFT_MAX\n");
239 qprint("growing continents...\n");
241 } while (fl_status && ++i < NUMTRIES);
243 fputs("ERROR: World not large enough to hold continents\n",
247 qprint("growing islands:");
249 qprint("\nelevating land...\n");
251 qprint("designating sectors...\n");
253 qprint("adding resources...\n");
255 qprint("writing to sectors file...\n");
256 if (write_file() == -1)
259 write_newcap_script();
268 puts("Creating a planet with:\n");
269 printf("%d continents\n", nc);
270 printf("continent size: %d\n", sc);
271 printf("number of islands: %d\n", ni);
272 printf("average size of islands: %d\n", is);
273 printf("spike: %d%%\n", sp);
274 printf("%d%% of land is mountain (each continent will have %d mountains)\n",
275 pm, (pm * sc) / 100);
276 printf("minimum distance between continents: %d\n", di);
277 printf("minimum distance from islands to continents: %d\n", id);
278 printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
286 for (i = 1; i * i < n * 10000; ++i) ;
287 return (i + 50) / 100;
290 /****************************************************************************
291 PARSE COMMAND LINE ARGUMENTS
292 ****************************************************************************/
295 parse_args(int argc, char *argv[])
297 if (argc < 2 || argc > 8) {
298 puts("fairland syntax:\n");
299 puts("fairland [-e config] [-aiqo] [-s script] <nc> <sc> [<ni>] [<is>] [<sp>] [<pm>] [<di>] [<id>]");
300 puts("-q = quiet, -o = no ore produced");
301 puts("-a = Airport marker for continents, -i = islands not distinct");
302 printf("-e = read config file, -s = name of script (default %s)\n",
304 puts("nc = number of continents [MANDATORY]");
305 puts("sc = continent size [MANDATORY]");
306 puts("ni = number of islands (default = nc)");
307 puts("is = average size of islands (default = sc/2)");
308 printf("sp = spike percentage: 0 = round, 100 = snake (default = %d)\n",
310 printf("pm = the percentage of land that is mountain (default = %d)\n",
312 printf("di = the minimum distance between continents (default = %d)\n",
314 printf("id = minimum distance from islands to continents (default = %d)\n",
320 puts("fairland: error -- number of continents must be > 0");
326 puts("fairland: error -- size of continents must be > 0");
354 pm = DEFAULT_MOUNTAIN;
361 di = DEFAULT_CONTDIST;
364 puts("fairland: error -- distance between continents must be >= 0");
367 if (di > WORLD_X / 2 || di > WORLD_Y / 2) {
368 puts("fairland: error -- distance between continents too large");
375 id = DEFAULT_ISLDIST;
377 puts("fairland: error -- distance from islands to continents must be >= 0");
380 if (id > WORLD_X || id > WORLD_Y) {
381 puts("fairland: error -- distance from islands to continents too large");
384 if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
385 puts("fairland: error -- world not big enough to fit continents.");
386 puts("arguments must satisfy:");
387 puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
392 /****************************************************************************
393 VARIABLE INITIALIZATION
394 ****************************************************************************/
397 allocate_memory(void)
404 open(empfile[EF_SECTOR].file, O_RDWR | O_CREAT | O_TRUNC, 0660);
407 open(empfile[EF_SECTOR].file,
408 O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0660);
411 perror(empfile[EF_SECTOR].file);
415 (struct sctstr *)calloc((YSIZE * XSIZE), sizeof(struct sctstr));
416 sects = (struct sctstr **)calloc(YSIZE, sizeof(struct sctstr *));
417 for (i = 0; i < YSIZE; i++)
418 sects[i] = §sbuf[XSIZE * i];
421 srandom(now + getpid());
425 capx = (int *)calloc(nc, sizeof(int));
426 capy = (int *)calloc(nc, sizeof(int));
427 vector = (int *)calloc(WORLD_X + WORLD_Y, sizeof(int));
428 mc = (int *)calloc(STABLE_CYCLE, sizeof(int));
429 own = (int **)calloc(WORLD_X, sizeof(int *));
430 elev = (int **)calloc(WORLD_X, sizeof(int *));
431 for (i = 0; i < WORLD_X; ++i) {
432 own[i] = (int *)calloc(WORLD_Y, sizeof(int));
433 elev[i] = (int *)calloc(WORLD_Y, sizeof(int));
435 sectx = (int **)calloc(nc + ni, sizeof(int *));
436 secty = (int **)calloc(nc + ni, sizeof(int *));
437 sectc = (int **)calloc(nc + ni, sizeof(int *));
438 isecs = (int *)calloc(nc + ni, sizeof(int));
439 weight = (int *)calloc(max(sc, is * 2), sizeof(int));
440 dsea = (int *)calloc(max(sc, is * 2), sizeof(int));
441 dmoun = (int *)calloc(max(sc, is * 2), sizeof(int));
442 for (i = 0; i < nc; ++i) {
443 sectx[i] = (int *)calloc(sc, sizeof(int));
444 secty[i] = (int *)calloc(sc, sizeof(int));
445 sectc[i] = (int *)calloc(sc, sizeof(int));
447 for (i = nc; i < nc + ni; ++i) {
448 sectx[i] = (int *)calloc(is * 2, sizeof(int));
449 secty[i] = (int *)calloc(is * 2, sizeof(int));
450 sectc[i] = (int *)calloc(is * 2, sizeof(int));
459 int i, j, xx = 0, yy = 0;
464 for (i = 0; i < WORLD_X; ++i) {
465 for (j = 0; j < WORLD_Y; ++j) {
467 elev[i][j] = -INFINITY;
471 for (i = 0; i < nc; ++i, xx += 2) {
476 puts("fairland error: world not big enough for all the continents.\n");
483 for (i = 0; i < STABLE_CYCLE; ++i)
487 /****************************************************************************
488 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
489 ****************************************************************************/
491 /* How isolated is capital j?
494 iso(int j, int newx, int newy)
496 int i, md, d = WORLD_X + WORLD_Y;
498 for (i = 0; i < nc; ++i) {
501 md = mapdist(capx[i], capy[i], newx, newy);
509 /* Drift all the capitals
516 for (turns = 0; turns < DRIFT_MAX; ++turns) {
517 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
519 for (i = 0; i < nc; ++i)
525 /* Check to see if we have stabilized--can we stop drifting the capitals?
531 int i, isod, d = 0, stab = 1;
533 for (i = 0; i < nc; ++i) {
534 isod = iso(i, capx[i], capy[i]);
538 for (i = 0; i < STABLE_CYCLE; ++i)
542 mcc = (mcc + 1) % STABLE_CYCLE;
546 /* This routine does the actual drifting
552 int i, n, newx, newy;
554 for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
555 newx = new_x(capx[j] + dirx[i]);
556 newy = new_y(capy[j] + diry[i]);
557 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
565 /****************************************************************************
567 ****************************************************************************/
569 /* Look for a coastal sector of continent c
577 for (i = 0; i < secs; ++i) {
579 for (j = 0; j < 6; ++j)
580 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
585 /* Used for measuring distances
597 for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
600 return i > 1 || vector[0] > 0;
603 /* Test to see if we're allowed to grow there: the arguments di and id
606 try_to_grow(int c, int newx, int newy, int d)
610 for (i = 1; i <= d; ++i) {
611 for (j = 0; j < i; ++j)
616 for (j = 0; j < i; ++j) {
617 px = new_x(px + dirx[vector[j]]);
618 py = new_y(py + diry[vector[j]]);
620 if (own[px][py] != -1 &&
622 (DISTINCT_ISLANDS || own[px][py] < nc))
624 } while (next_vector(i));
626 sectx[c][secs] = newx;
627 secty[c][secs] = newy;
632 /* Move along the coast in a clockwise direction.
636 next_coast(int c, int x, int y, int *xp, int *yp)
638 int i, nx, ny, wat = 0;
646 for (i = 0; i < 12; ++i) {
647 nx = new_x(x + dirx[i % 6]);
648 ny = new_y(y + diry[i % 6]);
649 if (own[nx][ny] == -1)
651 if (wat && own[nx][ny] == c) {
659 /* Choose a sector to grow from
671 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
676 } while (i != starti);
678 printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n",
687 /* Grow continent c by 1 sector
691 grow_one_sector(int c)
693 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
695 spike = rnd(100) < sp;
696 if ((try1 = new_try(c)) == -1)
698 x = sx = sectx[c][try1];
699 y = sy = secty[c][try1];
704 for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
705 newx = new_x(x + dirx[i]);
706 newy = new_y(y + diry[i]);
707 if (own[newx][newy] == -1 &&
709 (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
710 own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
711 if (try_to_grow(c, newx, newy, c < nc ? di : id))
715 for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
716 newx = new_x(x + dirx[i]);
717 newy = new_y(y + diry[i]);
718 if (own[newx][newy] == -1)
719 if (try_to_grow(c, newx, newy, c < nc ? di : id))
722 next_coast(c, x, y, &x, &y);
724 } while (!done && coast_search < COAST_SEARCH_MAX &&
725 (secs == 1 || x != sx || y != sy));
726 if (!done && c < nc) {
728 printf("fairland: error -- continent %c had no room to grow!\n",
730 fl_status |= STATUS_NO_ROOM;
735 /* Grow all the continents
738 grow_continents(void)
742 for (c = 0; c < nc; ++c) {
743 sectx[c][0] = capx[c];
744 secty[c][0] = capy[c];
745 own[sectx[c][0]][secty[c][0]] = c;
746 sectx[c][1] = new_x(capx[c] + 2);
747 secty[c][1] = capy[c];
748 own[sectx[c][1]][secty[c][1]] = c;
751 for (secs = 2; secs < sc && !fl_status; ++secs) {
752 for (c = 0; c < nc; ++c) {
757 if (fl_status && !quiet)
758 printf("Only managed to grow %d out of %d sectors.\n", secs, sc);
762 /****************************************************************************
764 ****************************************************************************/
766 /* Choose a place to start growing an island from
769 place_island(int c, int *xp, int *yp)
772 int ssy = rnd(WORLD_Y);
773 int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2);
775 if (ssx > WORLD_X - 2)
776 ssx = new_x(ssx + 2);
777 for (d = di + id; d >= id; --d) {
781 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
782 if (*xp >= WORLD_X) {
783 *yp = new_y(*yp + 1);
785 if (*xp == sx && *yp == sy)
788 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
795 /* Grow all the islands
803 for (c = nc; c < nc + ni; ++c) {
805 if (!place_island(c, &x, &y))
807 isiz = 1 + rnd(2 * is - 1);
811 } while (secs < isiz && grow_one_sector(c));
813 printf(" %d(%d)", c - nc + 1, secs);
819 /****************************************************************************
821 ****************************************************************************/
823 create_elevations(void)
829 /* Generic function for finding the distance to the closest sea, land, or
833 distance_to_what(int x, int y, int flag)
837 for (d = 1; d < 5; ++d) {
838 for (j = 0; j < d; ++j)
843 for (j = 0; j < d; ++j) {
844 px = new_x(px + dirx[vector[j]]);
845 py = new_y(py + diry[vector[j]]);
848 case 0: /* distance to sea */
849 if (own[px][py] == -1)
852 case 1: /* distance to land */
853 if (own[px][py] != -1)
856 case 2: /* distance to mountain */
857 if (elev[px][py] == INFINITY)
861 } while (next_vector(d));
866 #define ELEV elev[sectx[c][i]][secty[c][i]]
867 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
868 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
870 /* Decide where the mountains go
875 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
878 for (c = 0; c < ctot; ++c) {
880 ns = (c < nc) ? sc : isecs[c];
881 nm = (pm * ns) / 100;
883 /* Place the mountains */
885 for (i = 0; i < ns; ++i) {
886 dsea[i] = distance_to_sea();
887 weight[i] = (total += (dsea[i] * dsea[i]));
890 for (k = nm, mountain_search = 0;
891 k && mountain_search < MOUNTAIN_SEARCH_MAX;
894 for (i = 0; i < ns; ++i)
895 if (r < weight[i] && ELEV == -INFINITY &&
897 ((!(capx[c] == sectx[c][i] &&
898 capy[c] == secty[c][i])) &&
899 (!(new_x(capx[c] + 2) == sectx[c][i] &&
900 capy[c] == secty[c][i]))))) {
907 /* Elevate land that is not mountain and not capital */
909 for (i = 0; i < ns; ++i)
910 dmoun[i] = distance_to_mountain();
911 dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
912 (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
914 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
917 for (i = 0; i < ns; ++i) {
918 if (ELEV != INFINITY &&
919 (c >= nc || ((!(capx[c] == sectx[c][i] &&
920 capy[c] == secty[c][i])) &&
921 (!(new_x(capx[c] + 2) == sectx[c][i] &&
922 capy[c] == secty[c][i]))))) {
923 h = 3 * (5 - dmoun[i]) + dsea[i];
933 if (newk >= HILLMIN && newk < PLATMIN)
937 elev[sectx[c][where]][secty[c][where]] = newk;
938 dsea[where] = -INFINITY;
939 dmoun[where] = INFINITY;
942 /* Elevate the mountains and capitals */
944 for (i = 0; i < ns; ++i) {
945 if (ELEV == INFINITY) {
947 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
949 ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) +
950 rnd((256 - HIGHMIN) / 2);
951 } else if ((c < nc &&
952 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
953 ((new_x(capx[c] + 2) == sectx[c][i] &&
954 capy[c] == secty[c][i])))
960 #define distance_to_land() distance_to_what(x, y, 1)
967 for (y = 0; y < WORLD_Y; ++y) {
968 for (x = y % 2; x < WORLD_X; x += 2) {
969 if (elev[x][y] == -INFINITY)
970 elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
975 /****************************************************************************
977 ****************************************************************************/
984 fert = LANDMIN - e + 40;
985 else if (e < FERT_MAX)
986 fert = (140 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
997 oil = (LANDMIN - e) * 2 + rnd(2);
998 else if (e <= OIL_MAX)
999 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1009 if (e >= IRON_MIN && e < HIGHMIN)
1010 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1020 if (e >= GOLD_MIN) {
1022 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1024 gold = 100 - 20 * HIGHMIN / e;
1035 if (e >= URAN_MIN && e < HIGHMIN)
1036 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1043 add_resources(struct sctstr *sct)
1045 sct->sct_fertil = set_fert(sct->sct_elev);
1046 sct->sct_oil = set_oil(sct->sct_elev);
1047 sct->sct_min = set_iron(sct->sct_elev);
1048 sct->sct_gmin = set_gold(sct->sct_elev);
1049 sct->sct_uran = set_uran(sct->sct_elev);
1052 /****************************************************************************
1053 DESIGNATE THE SECTORS
1054 ****************************************************************************/
1059 register struct sctstr *sct;
1062 /* sct = §s[0][0]; */
1064 for (y = 0; y < YSIZE; y++) {
1065 for (x = 0; x < XSIZE; x++, sct++) {
1066 fl_sct_init(x * 2 + (y & 01), y, (s_char *)sct);
1067 total = elev[sct->sct_x][y];
1068 if (total < LANDMIN) {
1069 sct->sct_type = SCT_WATER;
1070 } else if (total < HILLMIN)
1071 sct->sct_type = SCT_RURAL;
1072 else if (total < PLATMIN)
1073 sct->sct_type = SCT_MOUNT;
1074 else if (total < HIGHMIN)
1075 sct->sct_type = SCT_RURAL;
1077 sct->sct_type = SCT_MOUNT;
1078 sct->sct_elev = total;
1079 sct->sct_newtype = sct->sct_type;
1085 for (c = 0; c < nc; ++c) {
1086 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_type = SCT_AIRPT;
1087 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_newtype = SCT_AIRPT;
1091 /****************************************************************************
1092 WRITE ALL THIS STUFF TO THE FILE
1093 ****************************************************************************/
1099 /* if ((n = write(the_file, sects, sizeof(sects))) < 0) { */
1100 if ((n = write(the_file, sectsbuf, YSIZE * XSIZE * sizeof(struct sctstr))) < 0) {
1101 perror(empfile[EF_SECTOR].file);
1104 if (n != (int)(YSIZE * XSIZE * sizeof(struct sctstr))) {
1105 printf("%s:partial write\n", empfile[EF_SECTOR].file);
1112 /****************************************************************************
1113 PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1114 ****************************************************************************/
1120 translate_continents();
1122 for (i = 0; i < WORLD_Y; ++i) {
1126 for (j = i % 2; j < WORLD_X; j += 2) {
1127 if (own[j][i] == -1)
1130 printf("%c ", map_symbol(j, i));
1136 printf("\n\nEach continent is marked by a \"*\" on the map (to distinguish them from\nthe islands). You can redesignate these airfields to wilderness sectors\none at a time, each time you add a new country to the game.\n");
1139 /* Reorder the continents from top left to bottom right */
1141 translate_continents(void)
1143 int i, j, n = 0, k, gotit, c;
1144 int *trans, *trans_cont, *oldcapx, *oldcapy;
1146 trans = (int *)calloc(nc, sizeof(int));
1147 trans_cont = (int *)calloc(nc, sizeof(int));
1148 oldcapx = (int *)calloc(nc, sizeof(int));
1149 oldcapy = (int *)calloc(nc, sizeof(int));
1151 for (i = 0; i < WORLD_Y; ++i) {
1152 for (j = i % 2; j < WORLD_X; j += 2) {
1153 if (own[j][i] > -1 && own[j][i] < nc) {
1155 for (k = 0; k < n; ++k) {
1156 if (trans[k] == own[j][i])
1161 printf("fairland: BUG in translate continents! mail stevens@math.utoronto.ca\n");
1164 trans[n] = own[j][i];
1165 trans_cont[own[j][i]] = n;
1171 for (i = 0; i < WORLD_Y; ++i) {
1172 for (j = i % 2; j < WORLD_X; j += 2) {
1173 if (own[j][i] > -1 && own[j][i] < nc) {
1174 own[j][i] = trans_cont[own[j][i]];
1178 for (c = 0; c < nc; ++c) {
1179 oldcapx[c] = capx[c];
1180 oldcapy[c] = capy[c];
1182 for (c = 0; c < nc; ++c) {
1183 capx[c] = oldcapx[trans[c]];
1184 capy[c] = oldcapy[trans[c]];
1189 map_symbol(int x, int y)
1193 for (c = 0; c < nc; ++c)
1194 if ((x == capx[c] && y == capy[c])
1195 || (x == new_x(capx[c] + 2) && y == capy[c]))
1197 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
1198 || elev[x][y] >= HIGHMIN)
1200 return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
1203 /***************************************************************************
1204 WRITE A SCRIPT FOR PLACING CAPITALS
1205 ****************************************************************************/
1207 write_newcap_script(void)
1210 FILE *script = fopen(outfile, "w");
1213 printf("fairland: error, unable to write to %s.\n", outfile);
1217 for (c = 0; c < nc; ++c) {
1218 fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1);
1220 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1221 fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1223 fprintf(script, "add %d visitor visitor v i\n", c + 1);
1227 printf("\n\nA script for adding all the countries can be found in \"%s\".\n",
1229 if (ORE && quiet == 0)
1230 printf("\t***IMPORTANT: Resources have already been added***\n\tYou do NOT need to run the ore program.\n");
1235 qprint(const char *str)
1242 fl_sct_init(coord x, coord y, s_char *ptr)
1244 struct sctstr *sp = (struct sctstr *)ptr;
1246 sp->ef_type = EF_SECTOR;
1253 sp->sct_defense = 0;