[net.sources.games] Map making program for empire

wws@whuxlm.UUCP (Stoll W William) (05/14/85)

The empire game that was posted recently was fun, but got tiresome
to use the same maps all the time.  A bit of poking using adb
revealed how maps are encoded; here's a program that converts an
ascii map to a coded version acceptable to empire.  It reads
the ascii map from standard input, and writes the coded
version to standard output.  Sample usage:

makmap <ascii.map >emp.map

Empire still requires that its input maps be named a.map or b.map,
so you will have to change the name of your object map accordingly.

Ascii input maps must be "on edge" (each line having 60 characters,
100 lines).  I arbitrarily set the city limit to 65 - a sample game
with 72 seemed to run very slowly, and possibly overwrote some
data structure somewhere (i dunno).

This program doesn't check for "cities on the edge".

Bill Stoll, ..!whuxlm!wws
#
# This is a shell archive.  Remove all lines above this one,
# then change directory to the place you want the files to
# go.  Type  sh filename  to extract the files.
# You will have to modify permissions manually, if desired
#
# This archive contains:
#	makmap.c
#
echo "extracting makmap.c:"
cat <<\E_O_F >makmap.c

#include <stdio.h>

#define ROWS 60
#define COLS 100
#define MAXCIT 65

char map[ROWS][COLS];

main()
{
	unsigned int c, bit;
	int citcnt;
	int ch;
	register int i, j, cnt;

	/* Read the map */
	citcnt = 0;
	for (i = 0; i < COLS; i++) {
		for (j = 0; j < ROWS; j++) {
			ch = getchar();
			switch(ch) {
				case '+':
				case '.':
					map[j][i] = ch;
					break;
				case '*':
					citcnt++;
					map[j][i] = ch;
					break;
				case '\n':
					fprintf(stderr,
				"Line too short; should be %d characters\n", ROWS);
					exit(1);

				case EOF:
					fprintf(stderr, "File not large enough\n");
					exit(1);
				default:
					fprintf(stderr,
				"Bad character '%c' (0x%02x)\n", ch, ch);
					exit(1);
			}
		}
		if ((ch = getchar()) != '\n') {
			fprintf(stderr, "Line too long; should be %d characters\n", ROWS);
			exit(1);
		}
	}
	if ((ch = getchar()) != EOF) {
		fprintf(stderr, "File too large; should have %d lines\n", COLS);
		exit(1);
	}
	if (citcnt > MAXCIT) {
		fprintf(stderr, "too many cities!  You had %d, max is %d\n", citcnt, MAXCIT);
		exit(1);
	}

	/* convert the map */
	cnt = -1;
	c = map[0][0];
	for (i = 0; i < ROWS; i++)
		for (j = 0; j < COLS; j++) {
			/* New map character? */
			if (c != map[i][j] || cnt == 63) {	/* yes */
				bit = (cnt << 2) | MCODE(c);
				putchar(bit);
				c = map[i][j];
				cnt = 0;
			} else
				cnt++;
		}
	putchar('\0');
	putchar('\0');
}

#define	LAND	3
#define	WATER	2
#define	CITY	1

/*
 * code '+', '.', '*' as 3, 2, or 1
 */
MCODE(c)
unsigned int c;
{
	switch(c) {
		case '+':
			return(LAND);
		case '.':
			return(WATER);
		case '*':
			return(CITY);
	}
	fprintf(stderr, "internal error\n");
	exit(1);
}
E_O_F
#
echo "All Files Extracted"

bright@dataio.UUCP (Walter Bright) (05/15/85)

For those of you using the map making program, some rules you
should follow are:

1) The maximum number of cities is 70. Exceeding this will cause
unpredictable program behavior. Less than 60 cities makes for a
boring game.

2) Do not put any cities on the edge of the map.

3) Island cities are OK (cities surrounded by water).

4) Do not make continents with only 1 city on them. These will cause
the computer strategy to fail.

5) Each continent needs at least 1 'port' city. Otherwise, if one
starts out on that continent, one can never get off it!

6) Do not have any 'lakes' with port cities on them.

Not following these rules will cause:

1) Program crashes (for 1) or 2)).

2) The computer strategy will fail.

3) A boring game.

These are the reasons why empire reads fixed data files instead
of randomly generating a map each time it is run.

Have fun!