Challenge 29 Sector Generator

By James T. Perkins ·

TML message #58From bundle 5

Marc Miller came up with a Applesoft Basic Traveller Sector Generator.
Well, here's the same thing in 3.6K of C-code (actually 6.2K with all
the comments), although it produces an expanded output format.

By clipping out strategic columns of text, you should be able to exactly
reproduce the output specification for Marc's program.

Note that the "extras" provided here include room for a 18-character
system name, produce the "Terran-Norm" and "Terran-Prime" output codes,
flag the presence of a planetoid belt (the last ("P") column), and
ignores the plethora of bugs present in the Applesoft listing in
Challenge (must've been typed in by hand, yech!).

Gee, this generates a lot of amber zone worlds (8- on 2D).

For you VMS people out there, this isn't a far deviation from the
standard C-library, so with a little adjustment it should work okay.

Enjoy, and please tell me if it was useful to you.

 _	___
| |    / _ \   James T. Perkins, [email removed], 629-1149
| |__ | |_| |  Tektronix Logic Analyzers, DAS System Software, Display
|[address removed]

Killed processes never die... They just go to the big Bit Bicket in the sky.

- ------- O/ cut here ----------
- ------- O\ snip snip ---------
/*

	gensec - a simplistic traveller sector generator

	Simplistic Traveller sector generator, based on Marc Miller,
	"Traveller Sector Generator", Using Your Model 2/BIS, Challenge
	No.  25; and other Traveller material (Books 3 and 6, and
	wherever T-norm, T-prime designations came from).

	The format of the output of gensec is a superset of the material
	produced by Mr.  Miller's published program.  A field is
	included for system name, and a "P" field in the last column
	notes the existence of a planetoid belt not in the main world
	orbit.

	This program rewritten C and Unix Aug 18 1987 by James T.
	Perkins.  ([email removed], [email removed])

	4.2BSD Unix sites Compile/link with: cc -s -O -o gensec gensec.c
	Sys V Unix sites Compile/link with: cc -s -O -o gensec -DSYSV gensec.c

	-----------------------------------------------------------------

	Copyright 1987 James T. Perkins

	This notice and any statement of authorship must be reproduced
	on all copies.  The author does not make any warranty expressed
	or implied, or assumes any liability or responsiblity for the
	use of this software.

	Any distributor of copies of this software shall grant the
	recipient permission for further redistribution as permitted
	by this notice.	 Any distributor must distribute this software
	without any fee or other monetary gains, unless expressed written
	permission is granted by the author.

	This software or its use shall not be: sold, rented, leased,
	traded, or otherwise marketed without the expressed written
	permission of the author.

	If the software is modified in a manner creating derivative
	copyrights, appropriate legends may be placed on derivative
	work in addition to that set forth above.

	Permission is hereby granted to copy, reproduce, redistribute or
	otherwise use this software as long as the conditions above
	are met.

	All rights not granted by this notice are reserved.

*/

/* System include files */
#include <stdio.h>
#include <strings.h>
#include <ctype.h>

/* Local macros */
#define D2 nd(2, 6)
#define D1 nd(2, 6)
#define DM(test, dm) ((test) ? (dm) : 0)
#define limit(x, l, u) (((x) < (l)) ? (l) : (((x) > (u)) ? (u) : (x)))

/* allows compilation on System V Unix */
#ifdef SYSV
#define random rand
#define srandom srand
#endif

/* Boolean type declaration */
typedef int bool;

/* External (system) functions */
extern long srandom(), random(), time();

/* Forward declarations */
char hexchar();

/* Source module globals */
static char *copyright = "Copyright 1987 James Perkins";

main(ac, av)
int ac;
char **av;
{
	int x, y;
	int genpctg = 50;
	char *progname;

	(void)srandom(time(NULL));

	progname = *av;
	av++; ac--;
	if (ac > 0)
	{
		if (isdigit(**av))
			genpctg = atoi(*av);
		else
		{
			fprintf(stderr, "usage: %s generation_percentage\n",
				progname);
			exit(1);
		}
	}

	for (x = 1; x <= 32; x++)
	{
		for (y = 1; y <= 40; y++)
		{
			if (d(100) < genpctg)
			{
				gensys(x, y, stdout);
			}
		}
	}
	exit(0);
}

gensys(x, y, fp)
int x, y;
FILE *fp;
{
	static char *nam = "Unnamed", *ali = "IM";
	char cla, bas, zon, tra[50], out[81];
	int siz, atm, hyd, pop, gov, law, tl;
	bool gas, sco, nav, pla;

	/* Starport class */
	cla = *("AAABBCCDEEX" + D2 - 2);

	/* Physical characteristics */
	siz = D2 - 2;
	atm = D2 - 7 + siz;
	atm = ((siz == 0) ? 0 : atm);
	atm = limit(atm, 0, 15);
	hyd = D2 - 7 + siz + ((atm < 2 || atm > 9) ? -4 : 0);
	hyd = ((siz < 2) ? 0 : hyd);
	hyd = limit(hyd, 0, 10);

	/* Demographics */
	pop = D2 - 2;
	gov = D2 - 7 + pop;
	gov = limit(gov, 0, 13);
	law = D2 - 7 + gov;
	law = limit(law, 0, 20);

	/* Technological level */
	tl = D1 + DM(cla == 'A', 6) + DM(cla == 'B', 4) + DM(cla == 'C', 2) +
		DM(cla == 'X', -4);
	tl = tl + DM(siz < 5, 1) + DM(siz < 2, 1);
	tl = tl + DM(atm < 4, 1) + DM(atm > 9 && atm < 15, 1);
	tl = tl + DM(hyd == 8, 1) + DM(hyd == 9, 2);
	tl = tl + DM(pop > 0 && pop < 6, 1) + DM(pop == 9, 2) +
		DM(pop == 10, 4);
	tl = tl + DM(gov == 0 || gov == 5, 1) + DM(gov == 13, -2);
	tl = limit(tl, 0, 15);

	/* System caharacteristics */
	gas = (D2 < 10);
	pla = (D2 < 7);

	/* Travel advisories */
	zon = ((cla == 'X') ? 'R' : ((D2 < 10) ? 'A' : ' '));

	/* Bases */
	nav = (cla < 'C' && D2 > 7);
	sco = (cla < 'E' && (D2 + DM(cla == 'A', -3) + DM(cla == 'B', -2) +
		DM(cla == 'C', -1) > 6));
	bas = (nav && sco ? 'A' : (nav ? 'N' : (sco ? 'S' : ' ')));

	/* Trade classifications */
	*tra = '\0';
	if (siz > 5 && atm > 3 && atm < 10 && hyd > 2 && hyd < 10)
	{
		if (siz > 6 && siz < 10 && atm > 5 && atm < 8 && hyd > 4 &&
			hyd < 8)
			strcat(tra, "TN ");	/* Terran-Norm */
		else
			strcat(tra, "TP ");	/* Terran-Prime */
	}
	if (atm > 3 && atm < 10 && hyd > 3 && hyd < 9 && pop > 4 && pop < 8)
		strcat(tra, "AG ");		/* Agricultural */
	if (atm < 4 && hyd < 4 && pop > 5)
		strcat(tra, "NA ");		/* Non-Agricultural */
	if ((atm < 3 || atm == 4 || atm == 7 || atm == 9) && pop > 8)
		strcat(tra, "IN ");		/* Industrial */
	if (pop < 7)
		strcat(tra, "NI ");		/* Non-Industrial */
	if ((atm == 6 || atm == 8) && pop > 5 && pop < 9 && gov > 3 && gov < 10)
		strcat(tra, "RI ");		/* Rich */
	if (atm > 1 && atm < 6 && hyd < 4)
		strcat(tra, "PO ");		/* Poor */
	if (hyd == 10)
		strcat(tra, "WA ");		/* Water World */
	if (hyd == 0 && atm > 1)
		strcat(tra, "DE ");		/* Desert World */
	if (siz == 0)
		strcat(tra, "AS ");		/* Asteroid Belt */
	if (atm == 0 && siz > 0)
		strcat(tra, "VA ");		/* Vaccuum World */
	if (pop == 0 && gov == 0 && law == 0)
		strcat(tra, "BA ");		/* ??? */

	/* Create world data string */
	sprintf(out, "%02d%02d %-18s %c%c%c%c%c%c%c-%c %c %-15s %2s %c %c%c\n",
		x, y, nam, cla,
		hexchar(siz), hexchar(atm), hexchar(hyd), hexchar(pop),
		hexchar(gov), hexchar(law), hexchar(tl),
		bas, tra, ali, zon, (gas ? 'G' : ' '), (pla ? 'P' : ' '));

	/* Write it out to file (or stdout) */
	fwrite(out, strlen(out), 1, fp);
}

char hexchar(i)
int i;
{
	if (i < 0 || i > 34)
		return '?';
	else
		return *("0123456789ABCDEFGHJKLMNPQRSTUVWXYZ" + i);
}

int d(nsides)
int nsides;
{
	return (int)(random() % (long)nsides + 1L);
}

int nd(ndice, nsides)
int ndice, nsides;
{
	if (ndice < 1)
	{
		return 0;
	}
	else
	{
		return nd(ndice - 1, nsides) + d(nsides);
	}
}