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 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
155 void parse_args(int argc, char *argv[]);
156 int allocate_memory(void);
159 void grow_continents(void);
160 void create_elevations(void);
161 void write_sects(void);
162 int write_file(void);
164 int write_newcap_script(void);
166 void elevate_land(void);
167 void elevate_sea(void);
168 void translate_continents(void);
169 int map_symbol(int x, int y);
170 static void fl_sct_init(coord x, coord y, s_char *ptr);
177 /****************************************************************************
179 ****************************************************************************/
182 main(int argc, char *argv[])
187 extern s_char *datadir;
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", stderr);
246 qprint ("growing islands:");
248 qprint ("\nelevating land...\n");
250 qprint ("designating sectors...\n");
252 qprint ("adding resources...\n");
254 qprint ("writing to sectors file...\n");
255 if (write_file() == -1)
258 write_newcap_script();
267 puts("Creating a planet with:\n");
268 printf("%d continents\n", nc);
269 printf("continent size: %d\n", sc);
270 printf("number of islands: %d\n", ni);
271 printf("average size of islands: %d\n", is);
272 printf("spike: %d%%\n", sp);
273 printf("%d%% of land is mountain (each continent will have %d mountains)\n",
275 printf("minimum distance between continents: %d\n", di);
276 printf("minimum distance from islands to continents: %d\n", id);
277 printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
286 for (i = 1; i*i < n*10000; ++i);
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", DEFAULT_SPIKE);
309 printf("pm = the percentage of land that is mountain (default = %d)\n", DEFAULT_MOUNTAIN);
310 printf("di = the minimum distance between continents (default = %d)\n", DEFAULT_CONTDIST);
311 printf("id = minimum distance from islands to continents (default = %d)\n", DEFAULT_ISLDIST);
316 puts("fairland: error -- number of continents must be > 0");
322 puts("fairland: error -- size of continents must be > 0");
350 pm = DEFAULT_MOUNTAIN;
357 di = DEFAULT_CONTDIST;
360 puts("fairland: error -- distance between continents must be >= 0");
363 if (di > WORLD_X/2 || di > WORLD_Y/2) {
364 puts("fairland: error -- distance between continents too large");
371 id = DEFAULT_ISLDIST;
373 puts("fairland: error -- distance from islands to continents must be >= 0");
376 if (id > WORLD_X || id > WORLD_Y) {
377 puts("fairland: error -- distance from islands to continents too large");
380 if (nc*sc + nc*my_sqrt(sc)*2*(di+1) > WORLD_X * WORLD_Y) {
381 puts("fairland: error -- world not big enough to fit continents.");
382 puts("arguments must satisfy:");
383 puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
388 /****************************************************************************
389 VARIABLE INITIALIZATION
390 ****************************************************************************/
393 allocate_memory(void)
399 the_file = open(empfile[EF_SECTOR].file, O_RDWR|O_CREAT|O_TRUNC, 0660);
401 the_file = open(empfile[EF_SECTOR].file, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0660);
404 perror(empfile[EF_SECTOR].file);
407 sectsbuf = (struct sctstr *)calloc((YSIZE * XSIZE), sizeof(struct sctstr));
408 sects = (struct sctstr **)calloc(YSIZE, sizeof(struct sctstr *));
409 for (i = 0; i < YSIZE; i++)
410 sects[i] = §sbuf[XSIZE * i];
413 srandom(now+getpid());
417 capx = (int *)calloc(nc, sizeof(int));
418 capy = (int *)calloc(nc, sizeof(int));
419 vector = (int *)calloc(WORLD_X+WORLD_Y, sizeof(int));
420 mc = (int *)calloc(STABLE_CYCLE, sizeof(int));
421 own = (int **)calloc(WORLD_X, sizeof(int*));
422 elev = (int **)calloc(WORLD_X, sizeof(int*));
423 for (i = 0; i < WORLD_X; ++i) {
424 own[i] = (int *)calloc(WORLD_Y, sizeof(int));
425 elev[i] = (int *)calloc(WORLD_Y, sizeof(int));
427 sectx = (int **)calloc(nc+ni, sizeof(int*));
428 secty = (int **)calloc(nc+ni, sizeof(int*));
429 sectc = (int **)calloc(nc+ni, sizeof(int*));
430 isecs = (int *)calloc(nc+ni, sizeof(int));
431 weight = (int *)calloc(max(sc,is*2), sizeof(int));
432 dsea = (int *)calloc(max(sc,is*2), sizeof(int));
433 dmoun = (int *)calloc(max(sc,is*2), sizeof(int));
434 for (i = 0; i < nc; ++i) {
435 sectx[i] = (int *)calloc(sc, sizeof(int));
436 secty[i] = (int *)calloc(sc, sizeof(int));
437 sectc[i] = (int *)calloc(sc, sizeof(int));
439 for (i = nc; i < nc+ni; ++i) {
440 sectx[i] = (int *)calloc(is*2, sizeof(int));
441 secty[i] = (int *)calloc(is*2, sizeof(int));
442 sectc[i] = (int *)calloc(is*2, sizeof(int));
451 int i, j, xx = 0, yy = 0;
456 for (i = 0; i < WORLD_X; ++i) {
457 for (j = 0; j < WORLD_Y; ++j) {
459 elev[i][j] = -INFINITY;
463 for (i = 0; i < nc; ++i, xx += 2) {
468 puts("fairland error: world not big enough for all the continents.\n");
475 for (i = 0; i < STABLE_CYCLE; ++i)
479 /****************************************************************************
480 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
481 ****************************************************************************/
483 /* How isolated is capital j?
489 int i, md, d = WORLD_X + WORLD_Y;
491 for (i = 0; i < nc; ++i) {
494 md = mapdist(capx[i], capy[i], newx, newy);
502 /* Drift all the capitals
509 for (turns = 0; turns < DRIFT_MAX; ++turns) {
510 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
512 for (i = 0; i < nc; ++i)
518 /* Check to see if we have stabilized--can we stop drifting the capitals?
524 int i, isod, d = 0, stab = 1;
526 for (i = 0; i < nc; ++i) {
527 isod = iso(i, capx[i], capy[i]);
531 for (i = 0; i < STABLE_CYCLE; ++i)
535 mcc = (mcc + 1) % STABLE_CYCLE;
539 /* This routine does the actual drifting
546 int i, n, newx, newy;
548 for (i = rnd(6), n = 0; n < 6; i = (i + 1)%6, ++n) {
549 newx = new_x(capx[j] + dirx[i]);
550 newy = new_y(capy[j] + diry[i]);
551 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
559 /****************************************************************************
561 ****************************************************************************/
563 /* Look for a coastal sector of continent c
572 for (i = 0; i < secs; ++i) {
574 for (j = 0; j < 6; ++j)
575 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
580 /* Used for measuring distances
593 for (i = 1; i < n && vector[i] == vector[i-1]; ++i);
596 return i > 1 || vector[0] > 0;
599 /* Test to see if we're allowed to grow there: the arguments di and id
602 try_to_grow(c, newx, newy, d)
603 int c, newx, newy, d;
607 for (i = 1; i <= d; ++i) {
608 for (j = 0; j < i; ++j)
613 for (j = 0; j < i; ++j) {
614 px = new_x(px + dirx[vector[j]]);
615 py = new_y(py + diry[vector[j]]);
617 if (own[px][py] != -1 &&
619 (DISTINCT_ISLANDS || own[px][py] < nc))
621 } while (next_vector(i));
623 sectx[c][secs] = newx;
624 secty[c][secs] = newy;
629 /* Move along the coast in a clockwise direction.
633 next_coast(c, x, y, xp, yp)
634 int c, x, y, *xp, *yp;
636 int i, nx, ny, wat = 0;
644 for (i = 0; i < 12; ++i) {
645 nx = new_x(x+dirx[i%6]);
646 ny = new_y(y+diry[i%6]);
647 if (own[nx][ny] == -1)
649 if (wat && own[nx][ny] == c) {
657 /* Choose a sector to grow from
670 i = starti = (spike && sectc[c][secs-1])?secs-1:rnd(secs);
675 } while (i != starti);
677 printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n", c + 'a', secs);
686 /* Grow continent c by 1 sector
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))
716 for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1)%6, ++n) {
717 newx = new_x(x+dirx[i]);
718 newy = new_y(y+diry[i]);
719 if (own[newx][newy] == -1)
720 if (try_to_grow(c, newx, newy, c<nc?di:id))
723 next_coast(c, x, y, &x, &y);
725 } while (!done && coast_search < COAST_SEARCH_MAX &&
726 (secs == 1 || x != sx || y != sy));
727 if (!done && c < nc) {
729 printf("fairland: error -- continent %c had no room to grow!\n",
731 fl_status |= STATUS_NO_ROOM;
736 /* Grow all the continents
739 grow_continents(void)
743 for (c = 0; c < nc; ++c) {
744 sectx[c][0] = capx[c];
745 secty[c][0] = capy[c];
746 own[sectx[c][0]][secty[c][0]] = c;
747 sectx[c][1] = new_x(capx[c] + 2);
748 secty[c][1] = capy[c];
749 own[sectx[c][1]][secty[c][1]] = c;
752 for (secs = 2; secs < sc && !fl_status; ++secs) {
753 for (c = 0; c < nc; ++c) {
758 if (fl_status && !quiet)
759 printf("Only managed to grow %d out of %d sectors.\n", secs, sc);
763 /****************************************************************************
765 ****************************************************************************/
767 /* Choose a place to start growing an island from
770 place_island(c, xp, yp)
774 int ssy = rnd(WORLD_Y);
775 int ssx = new_x(rnd(WORLD_X/2)*2 + ssy%2);
777 if (ssx > WORLD_X - 2)
778 ssx = new_x(ssx + 2);
779 for (d = di + id; d >= id; --d) {
783 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
784 if (*xp >= WORLD_X) {
785 *yp = new_y(*yp + 1);
787 if (*xp == sx && *yp == sy)
790 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
797 /* Grow all the islands
805 for (c = nc; c < nc+ni; ++c) {
807 if (!place_island(c, &x, &y))
809 isiz = 1 + rnd(2*is - 1);
813 } while (secs < isiz && grow_one_sector(c));
814 if (quiet == 0) printf(" %d(%d)", c - nc + 1, secs);
820 /****************************************************************************
822 ****************************************************************************/
824 create_elevations(void)
830 /* Generic function for finding the distance to the closest sea, land, or
834 distance_to_what(x,y,flag)
839 for (d = 1; d < 5; ++d) {
840 for (j = 0; j < d; ++j)
845 for (j = 0; j < d; ++j) {
846 px = new_x(px + dirx[vector[j]]);
847 py = new_y(py + diry[vector[j]]);
850 case 0: /* distance to sea */
851 if (own[px][py] == -1)
854 case 1: /* distance to land */
855 if (own[px][py] != -1)
858 case 2: /* distance to mountain */
859 if (elev[px][py] == INFINITY)
863 } while (next_vector(d));
868 #define ELEV elev[sectx[c][i]][secty[c][i]]
869 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
870 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
872 /* Decide where the mountains go
877 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk, r, dk;
879 for (c = 0; c < ctot; ++c) {
881 ns = (c < nc)?sc:isecs[c];
884 /* Place the mountains */
886 for (i = 0; i < ns; ++i) {
887 dsea[i] = distance_to_sea();
888 weight[i] = (total += (dsea[i]*dsea[i]));
891 for (k = nm, mountain_search = 0;
892 k && mountain_search < MOUNTAIN_SEARCH_MAX;
895 for (i = 0; i < ns; ++i)
896 if (r < weight[i] && ELEV == -INFINITY && (c >= nc ||
897 ((!(capx[c] == sectx[c][i] && capy[c] == secty[c][i])) &&
898 (!(new_x(capx[c] + 2) == sectx[c][i] && capy[c] == secty[c][i]))))) {
905 /* Elevate land that is not mountain and not capital */
907 for (i = 0; i < ns; ++i)
908 dmoun[i] = distance_to_mountain();
909 dk=(ns-nm-((c<nc)?3:1)>0)?(100*(HIGHMIN-LANDMIN))/(ns-nm-((c<nc)?3:1)):100*INFINITY;
910 for (k = 100*(HIGHMIN - 1);; k -= dk) {
913 for (i = 0; i < ns; ++i) {
914 if (ELEV != INFINITY && (c >= nc ||
915 ((!(capx[c] == sectx[c][i] && capy[c] == secty[c][i])) &&
916 (!(new_x(capx[c] + 2) == sectx[c][i] && capy[c] == secty[c][i])))))
918 h = 3*(5 - dmoun[i]) + dsea[i];
928 if (newk >= HILLMIN && newk < PLATMIN)
932 elev[sectx[c][where]][secty[c][where]] = newk;
933 dsea[where] = -INFINITY;
934 dmoun[where] = INFINITY;
937 /* Elevate the mountains and capitals */
939 for (i = 0; i < ns; ++i) {
940 if (ELEV == INFINITY) {
942 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
944 ELEV = HIGHMIN + rnd((256-HIGHMIN)/2) + rnd((256-HIGHMIN)/2);
947 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
948 ((new_x(capx[c] + 2) == sectx[c][i] && capy[c] == secty[c][i])))
954 #define distance_to_land() distance_to_what(x, y, 1)
961 for (y = 0; y < WORLD_Y; ++y) {
962 for (x = y%2; x < WORLD_X; x +=2) {
963 if (elev[x][y] == -INFINITY)
964 elev[x][y] = - rnd((distance_to_land()*20 + 27)) - 1;
969 /****************************************************************************
971 ****************************************************************************/
979 fert = LANDMIN - e + 40;
980 else if (e < FERT_MAX)
981 fert = (140*(FERT_MAX - e))/(FERT_MAX - LANDMIN);
993 oil = (LANDMIN - e)*2 + rnd(2);
994 else if (e <= OIL_MAX)
995 oil = (120*(OIL_MAX - e + 1))/(OIL_MAX - LANDMIN + 1);
1006 if (e >= IRON_MIN && e < HIGHMIN)
1007 iron = (120*(e - IRON_MIN + 1))/(HIGHMIN - IRON_MIN);
1018 if (e >= GOLD_MIN) {
1020 gold = (80*(e - GOLD_MIN + 1))/(HIGHMIN - GOLD_MIN);
1022 gold = 100 - 20 * HIGHMIN / e;
1034 if (e >= URAN_MIN && e < HIGHMIN)
1035 uran = (120*(e - URAN_MIN + 1))/(HIGHMIN - URAN_MIN);
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]) || (x == new_x(capx[c]+2) && y == capy[c]))
1196 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN) || elev[x][y] >= HIGHMIN)
1198 return own[x][y]>=nc?'%':iscap?'#':numletter[own[x][y] % 62];
1201 /***************************************************************************
1202 WRITE A SCRIPT FOR PLACING CAPITALS
1203 ****************************************************************************/
1205 write_newcap_script(void)
1208 FILE *script = fopen(outfile, "w");
1211 printf("fairland: error, unable to write to %s.\n", outfile);
1215 for (c = 0; c < nc; ++c) {
1216 fprintf(script, "add %d %d %d n i\n", c+1, c+1, c+1);
1218 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1219 fprintf(script, "newcap %d %d,%d\n", c+1, capx[c], capy[c]);
1221 fprintf(script, "add %d visitor visitor v i\n", c+1);
1225 printf("\n\nA script for adding all the countries can be found in \"%s\".\n",
1227 if (ORE && quiet == 0)
1228 printf("\t***IMPORTANT: Resources have already been added***\n\tYou do NOT need to run the ore program.\n");
1232 static void qprint (str)
1236 fputs (str, stdout);
1240 fl_sct_init(coord x, coord y, s_char *ptr)
1242 struct sctstr *sp = (struct sctstr *) ptr;
1244 sp->ef_type = EF_SECTOR;
1251 sp->sct_defense = 0;