Example #1
0
long
getynpar(const char *s)
{
	struct cvntab		*r;

	r = getcodpar(s, Yntab);
	return ((long) r->value);
}
Example #2
0
void play()
{
    while (1) {
	Move.free = 1;
	Move.time = 0.0;
	Move.shldchg = 0;
	Move.newquad = 0;
	Move.resting = 0;
	skiptonl(0);
	const struct cvntab* r = getcodpar("\nCommand", Comtab);
	(*r->value)(r->value2);
	events(0);
	attack(0);
	checkcond();
    }
}
Example #3
0
void
setup()
{
	const struct cvntab	*r;
	int			i, j;
	double			f;
	int			d;
	int			klump;
	int			ix, iy;
	struct quad		*q;
	struct event		*e;

	while (1)
	{
		r = getcodpar("What length game", Lentab);
		Game.length = (long) r->value;
		if (Game.length == 0)
		{
			if (restartgame())
				continue;
			return;
		}
		break;
	}
	r = getcodpar("What skill game", Skitab);
	Game.skill = (long) r->value;
	Game.tourn = 0;
	getstrpar("Enter a password", Game.passwd, 14, 0);
	if (strcmp(Game.passwd, "tournament") == 0)
	{
		getstrpar("Enter tournament code", Game.passwd, 14, 0);
		Game.tourn = 1;
		d = 0;
		for (i = 0; Game.passwd[i]; i++)
			d += Game.passwd[i] << i;
		srand(d);
	}
	Param.bases = Now.bases = ranf(6 - Game.skill) + 2;
	if (Game.skill == 6)
		Param.bases = Now.bases = 1;
	Param.time = Now.time = 6.0 * Game.length + 2.0;
	i = Game.skill;
	j = Game.length;
	Param.klings = Now.klings = i * j * 3.5 * (franf() + 0.75);
	if (Param.klings < i * j * 5)
		Param.klings = Now.klings = i * j * 5;
	if (Param.klings <= i)		/* numerical overflow problems */
		Param.klings = Now.klings = 127;
	Param.energy = Ship.energy = 5000;
	Param.torped = Ship.torped = 10;
	Ship.ship = ENTERPRISE;
	Ship.shipname = "Enterprise";
	Param.shield = Ship.shield = 1500;
	Param.resource = Now.resource = Param.klings * Param.time;
	Param.reserves = Ship.reserves = (6 - Game.skill) * 2.0;
	Param.crew = Ship.crew = 387;
	Param.brigfree = Ship.brigfree = 400;
	Ship.shldup = 1;
	Ship.cond = GREEN;
	Ship.warp = 5.0;
	Ship.warp2 = 25.0;
	Ship.warp3 = 125.0;
	Ship.sinsbad = 0;
	Ship.cloaked = 0;
	Param.date = Now.date = (ranf(20) + 20) * 100;
	f = Game.skill;
	f = log(f + 0.5);
	for (i = 0; i < NDEV; i++)
		if (Device[i].name[0] == '*')
			Param.damfac[i] = 0;
		else
			Param.damfac[i] = f;
	/* these probabilities must sum to 1000 */
	Param.damprob[WARP] = 70;	/* warp drive		 7.0% */
	Param.damprob[SRSCAN] = 110;	/* short range scanners	11.0% */
	Param.damprob[LRSCAN] = 110;	/* long range scanners	11.0% */
	Param.damprob[PHASER] = 125;	/* phasers		12.5% */
	Param.damprob[TORPED] = 125;	/* photon torpedoes	12.5% */
	Param.damprob[IMPULSE] = 75;	/* impulse engines	 7.5% */
	Param.damprob[SHIELD] = 150;	/* shield control	15.0% */
	Param.damprob[COMPUTER] = 20;	/* computer		 2.0% */
	Param.damprob[SSRADIO] = 35;	/* subspace radio	 3.5% */
	Param.damprob[LIFESUP] = 30;	/* life support		 3.0% */
	Param.damprob[SINS] = 20;	/* navigation system	 2.0% */
	Param.damprob[CLOAK] = 50;	/* cloaking device	 5.0% */
	Param.damprob[XPORTER] = 80;	/* transporter		 8.0% */
	/* check to see that I didn't blow it */
	for (i = j = 0; i < NDEV; i++)
		j += Param.damprob[i];
	if (j != 1000)
		errx(1, "Device probabilities sum to %d", j);
	Param.dockfac = 0.5;
	Param.regenfac = (5 - Game.skill) * 0.05;
	if (Param.regenfac < 0.0)
		Param.regenfac = 0.0;
	Param.warptime = 10;
	Param.stopengy = 50;
	Param.shupengy = 40;
	i = Game.skill;
	Param.klingpwr = 100 + 150 * i;
	if (i >= 6)
		Param.klingpwr += 150;
	Param.phasfac = 0.8;
	Param.hitfac = 0.5;
	Param.klingcrew = 200;
	Param.srndrprob = 0.0035;
	Param.moveprob[KM_OB] = 45;
	Param.movefac[KM_OB] = .09;
	Param.moveprob[KM_OA] = 40;
	Param.movefac[KM_OA] = -0.05;
	Param.moveprob[KM_EB] = 40;
	Param.movefac[KM_EB] = 0.075;
	Param.moveprob[KM_EA] = 25 + 5 * Game.skill;
	Param.movefac[KM_EA] = -0.06 * Game.skill;
	Param.moveprob[KM_LB] = 0;
	Param.movefac[KM_LB] = 0.0;
	Param.moveprob[KM_LA] = 10 + 10 * Game.skill;
	Param.movefac[KM_LA] = 0.25;
	Param.eventdly[E_SNOVA] = 0.5;
	Param.eventdly[E_LRTB] = 25.0;
	Param.eventdly[E_KATSB] = 1.0;
	Param.eventdly[E_KDESB] = 3.0;
	Param.eventdly[E_ISSUE] = 1.0;
	Param.eventdly[E_SNAP] = 0.5;
	Param.eventdly[E_ENSLV] = 0.5;
	Param.eventdly[E_REPRO] = 2.0;
	Param.navigcrud[0] = 1.50;
	Param.navigcrud[1] = 0.75;
	Param.cloakenergy = 1000;
	Param.energylow = 1000;
	for (i = 0; i < MAXEVENTS; i++)
	{
		e = &Event[i];
		e->date = 1e50;
		e->evcode = 0;
	}
	xsched(E_SNOVA, 1, 0, 0, 0);
	xsched(E_LRTB, Param.klings, 0, 0, 0);
	xsched(E_KATSB, 1, 0, 0, 0);
	xsched(E_ISSUE, 1, 0, 0, 0);
	xsched(E_SNAP, 1, 0, 0, 0);
	Ship.sectx = ranf(NSECTS);
	Ship.secty = ranf(NSECTS);
	Game.killk = Game.kills = Game.killb = 0;
	Game.deaths = Game.negenbar = 0;
	Game.captives = 0;
	Game.killinhab = 0;
	Game.helps = 0;
	Game.killed = 0;
	Game.snap = 0;
	Move.endgame = 0;

	/* setup stars */
	for (i = 0; i < NQUADS; i++)
		for (j = 0; j < NQUADS; j++)
		{
			q = &Quad[i][j];
			q->klings = q->bases = 0;
			q->scanned = -1;
			q->stars = ranf(9) + 1;
			q->holes = ranf(3) - q->stars / 5;
			if (q->holes < 0)
				q->holes = 0;
			q->qsystemname = 0;
		}

	/* select inhabited starsystems */
	for (d = 1; d < NINHAB; d++)
	{
		do
		{
			i = ranf(NQUADS);
			j = ranf(NQUADS);
			q = &Quad[i][j];
		} while (q->qsystemname);
		q->qsystemname = d;
	}

	/* position starbases */
	for (i = 0; i < Param.bases; i++)
	{
		while (1)
		{
			ix = ranf(NQUADS);
			iy = ranf(NQUADS);
			q = &Quad[ix][iy];
			if (q->bases > 0)
				continue;
			break;
		}
		q->bases = 1;
		Now.base[i].x = ix;
		Now.base[i].y = iy;
		q->scanned = 1001;
		/* start the Enterprise near starbase */
		if (i == 0)
		{
			Ship.quadx = ix;
			Ship.quady = iy;
		}
	}

	/* position klingons */
	for (i = Param.klings; i > 0; )
	{
		klump = ranf(4) + 1;
		if (klump > i)
			klump = i;
		while (1)
		{
			ix = ranf(NQUADS);
			iy = ranf(NQUADS);
			q = &Quad[ix][iy];
			if (q->klings + klump > MAXKLQUAD)
				continue;
			q->klings += klump;
			i -= klump;
			break;
		}
	}

	/* initialize this quadrant */
	printf("%d Klingons\n%d starbase", Param.klings, Param.bases);
	if (Param.bases > 1)
		printf("s");
	printf(" at %d,%d", Now.base[0].x, Now.base[0].y);
	for (i = 1; i < Param.bases; i++)
		printf(", %d,%d", Now.base[i].x, Now.base[i].y);
	printf("\nIt takes %d units to kill a Klingon\n", Param.klingpwr);
	Move.free = 0;
	initquad(0);
	srscan(1);
	attack(0);
}
Example #4
0
phaser()
{
	register int		i;
	int			j;
	register struct kling	*k;
	double			dx, dy;
	double			anglefactor, distfactor;
	register struct banks	*b;
	int			manual, flag, extra;
	int			hit;
	double			tot;
	int			n;
	int			hitreqd[NBANKS];
	struct banks		bank[NBANKS];
	struct cvntab		*ptr;

	if (Ship.cond == DOCKED)
		return(printf("Phasers cannot fire through starbase shields\n"));
	if (damaged(PHASER))
		return (out(PHASER));
	if (Ship.shldup)
		return (printf("Sulu: Captain, we cannot fire through shields.\n"));
	if (Ship.cloaked)
	{
		printf("Sulu: Captain, surely you must realize that we cannot fire\n");
		printf("  phasers with the cloaking device up.\n");
		return;
	}

	/* decide if we want manual or automatic mode */
	manual = 0;
	if (testnl())
	{
		if (damaged(COMPUTER))
		{
			printf(Device[COMPUTER].name);
			manual++;
		}
		else
			if (damaged(SRSCAN))
			{
				printf(Device[SRSCAN].name);
				manual++;
			}
		if (manual)
			printf(" damaged, manual mode selected\n");
	}

	if (!manual)
	{
		ptr = getcodpar("Manual or automatic", Matab);
		manual = (int) ptr->value;
	}
	if (!manual && damaged(COMPUTER))
	{
		printf("Computer damaged, manual selected\n");
		skiptonl(0);
		manual++;
	}

	/* initialize the bank[] array */
	flag = 1;
	for (i = 0; i < NBANKS; i++)
		bank[i].units = 0;
	if (manual)
	{
		/* collect manual mode statistics */
		while (flag)
		{
			printf("%d units available\n", Ship.energy);
			extra = 0;
			flag = 0;
			for (i = 0; i < NBANKS; i++)
			{
				b = &bank[i];
				printf("\nBank %d:\n", i);
				hit = getintpar("units");
				if (hit < 0)
					return;
				if (hit == 0)
					break;
				extra += hit;
				if (extra > Ship.energy)
				{
					printf("available energy exceeded.  ");
					skiptonl(0);
					flag++;
					break;
				}
				b->units = hit;
				hit = getintpar("course");
				if (hit < 0 || hit > 360)
					return;
				b->angle = hit * 0.0174532925;
				b->spread = getfltpar("spread");
				if (b->spread < 0 || b->spread > 1)
					return;
			}
			Ship.energy -= extra;
		}
		extra = 0;
	}
	else
	{
		/* automatic distribution of power */
		if (Etc.nkling <= 0)
			return (printf("Sulu: But there are no Klingons in this quadrant\n"));
		printf("Phasers locked on target.  ");
		while (flag)
		{
			printf("%d units available\n", Ship.energy);
			hit = getintpar("Units to fire");
			if (hit <= 0)
				return;
			if (hit > Ship.energy)
			{
				printf("available energy exceeded.  ");
				skiptonl(0);
				continue;
			}
			flag = 0;
			Ship.energy -= hit;
			extra = hit;
			n = Etc.nkling;
			if (n > NBANKS)
				n = NBANKS;
			tot = n * (n + 1) / 2;
			for (i = 0; i < n; i++)
			{
				k = &Etc.klingon[i];
				b = &bank[i];
				distfactor = k->dist;
				anglefactor = ALPHA * BETA * OMEGA / (distfactor * distfactor + EPSILON);
				anglefactor *= GAMMA;
				distfactor = k->power;
				distfactor /= anglefactor;
				hitreqd[i] = distfactor + 0.5;
				dx = Ship.sectx - k->x;
				dy = k->y - Ship.secty;
				b->angle = atan2(dy, dx);
				b->spread = 0.0;
				b->units = ((n - i) / tot) * extra;
#				ifdef xTRACE
				if (Trace)
				{
					printf("b%d hr%d u%d df%.2f af%.2f\n",
						i, hitreqd[i], b->units,
						distfactor, anglefactor);
				}
#				endif
				extra -= b->units;
				hit = b->units - hitreqd[i];
				if (hit > 0)
				{
					extra += hit;
					b->units -= hit;
				}
			}

			/* give out any extra energy we might have around */
			if (extra > 0)
			{
				for (i = 0; i < n; i++)
				{
					b = &bank[i];
					hit = hitreqd[i] - b->units;
					if (hit <= 0)
						continue;
					if (hit >= extra)
					{
						b->units += extra;
						extra = 0;
						break;
					}
					b->units = hitreqd[i];
					extra -= hit;
				}
				if (extra > 0)
					printf("%d units overkill\n", extra);
			}
		}
	}

#	ifdef xTRACE
	if (Trace)
	{
		for (i = 0; i < NBANKS; i++)
		{
			b = &bank[i];
			printf("b%d u%d", i, b->units);
			if (b->units > 0)
				printf(" a%.2f s%.2f\n", b->angle, b->spread);
			else
				printf("\n");
		}
	}
#	endif

	/* actually fire the shots */
	Move.free = 0;
	for (i = 0; i < NBANKS; i++)
	{
		b = &bank[i];
		if (b->units <= 0)
		{
			continue;
		}
		printf("\nPhaser bank %d fires:\n", i);
		n = Etc.nkling;
		k = Etc.klingon;
		for (j = 0; j < n; j++)
		{
			if (b->units <= 0)
				break;
			/*
			** The formula for hit is as follows:
			**
			**  zap = OMEGA * [(sigma + ALPHA) * (rho + BETA)]
			**	/ (dist ** 2 + EPSILON)]
			**	* [cos(delta * sigma) + GAMMA]
			**	* hit
			**
			** where sigma is the spread factor,
			** rho is a random number (0 -> 1),
			** GAMMA is a crud factor for angle (essentially
			**	cruds up the spread factor),
			** delta is the difference in radians between the
			**	angle you are shooting at and the actual
			**	angle of the klingon,
			** ALPHA scales down the significance of sigma,
			** BETA scales down the significance of rho,
			** OMEGA is the magic number which makes everything
			**	up to "* hit" between zero and one,
			** dist is the distance to the klingon
			** hit is the number of units in the bank, and
			** zap is the amount of the actual hit.
			**
			** Everything up through dist squared should maximize
			** at 1.0, so that the distance factor is never
			** greater than one.  Conveniently, cos() is
			** never greater than one, but the same restric-
			** tion applies.
			*/
			distfactor = BETA + franf();
			distfactor *= ALPHA + b->spread;
			distfactor *= OMEGA;
			anglefactor = k->dist;
			distfactor /= anglefactor * anglefactor + EPSILON;
			distfactor *= b->units;
			dx = Ship.sectx - k->x;
			dy = k->y - Ship.secty;
			anglefactor = atan2(dy, dx) - b->angle;
			anglefactor = cos((anglefactor * b->spread) + GAMMA);
			if (anglefactor < 0.0)
			{
				k++;
				continue;
			}
			hit = anglefactor * distfactor + 0.5;
			k->power -= hit;
			printf("%d unit hit on Klingon", hit);
			if (!damaged(SRSCAN))
				printf(" at %d,%d", k->x, k->y);
			printf("\n");
			b->units -= hit;
			if (k->power <= 0)
			{
				killk(k->x, k->y);
				continue;
			}
			k++;
		}
	}

	/* compute overkill */
	for (i = 0; i < NBANKS; i++)
		extra += bank[i].units;
	if (extra > 0)
		printf("\n%d units expended on empty space\n", extra);
}
Example #5
0
computer()
{
	int			ix, iy;
	register int		i, j;
	int			numout;
	int			tqx, tqy;
	struct cvntab		*r;
	int			cost;
	int			course;
	double			dist, time;
	double			warpfact;
	struct quad		*q;
	register struct event	*e;

	if (check_out(COMPUTER))
		return;
	while (1)
	{
		r = getcodpar("\nRequest", Cputab);
		switch ((int)r->value)
		{

		  case 1:			/* star chart */
			printf("Computer record of galaxy for all long range sensor scans\n\n");
			printf("  ");
			/* print top header */
			for (i = 0; i < NQUADS; i++)
				printf("-%d- ", i);
			printf("\n");
			for (i = 0; i < NQUADS; i++)
			{
				printf("%d ", i);
				for (j = 0; j < NQUADS; j++)
				{
					if (i == Ship.quadx && j == Ship.quady)
					{
						printf("$$$ ");
						continue;
					}
					q = &Quad[i][j];
					/* 1000 or 1001 is special case */
					if (q->scanned >= 1000)
						if (q->scanned > 1000)
							printf(".1. ");
						else
							printf("/// ");
					else
						if (q->scanned < 0)
							printf("... ");
						else
							printf("%3d ", q->scanned);
				}
				printf("%d\n", i);
			}
			printf("  ");
			/* print bottom footer */
			for (i = 0; i < NQUADS; i++)
				printf("-%d- ", i);
			printf("\n");
			break;

		  case 2:			/* trajectory */
			if (check_out(SRSCAN))
			{
				break;
			}
			if (Etc.nkling <= 0)
			{
				printf("No Klingons in this quadrant\n");
				break;
			}
			/* for each Klingon, give the course & distance */
			for (i = 0; i < Etc.nkling; i++)
			{
				printf("Klingon at %d,%d", Etc.klingon[i].x, Etc.klingon[i].y);
				course = kalc(Ship.quadx, Ship.quady, Etc.klingon[i].x, Etc.klingon[i].y, &dist);
				prkalc(course, dist);
			}
			break;

		  case 3:			/* course calculation */
			if (readdelim('/'))
			{
				tqx = Ship.quadx;
				tqy = Ship.quady;
			}
			else
			{
				ix = getintpar("Quadrant");
				if (ix < 0 || ix >= NSECTS)
					break;
				iy = getintpar("q-y");
				if (iy < 0 || iy >= NSECTS)
					break;
				tqx = ix;
				tqy = iy;
			}
			ix = getintpar("Sector");
			if (ix < 0 || ix >= NSECTS)
				break;
			iy = getintpar("s-y");
			if (iy < 0 || iy >= NSECTS)
				break;
			course = kalc(tqx, tqy, ix, iy, &dist);
			if (r->value2)
			{
				warp(-1, course, dist);
				break;
			}
			printf("%d,%d/%d,%d to %d,%d/%d,%d",
				Ship.quadx, Ship.quady, Ship.sectx, Ship.secty, tqx, tqy, ix, iy);
			prkalc(course, dist);
			break;

		  case 4:			/* score */
			score();
			break;

		  case 5:			/* phaser effectiveness */
			dist = getfltpar("range");
			if (dist < 0.0)
				break;
			dist *= 10.0;
			cost = pow(0.90, dist) * 98.0 + 0.5;
			printf("Phasers are %d%% effective at that range\n", cost);
			break;

		  case 6:			/* warp cost (time/energy) */
			dist = getfltpar("distance");
			if (dist < 0.0)
				break;
			warpfact = getfltpar("warp factor");
			if (warpfact <= 0.0)
				warpfact = Ship.warp;
			cost = (dist + 0.05) * warpfact * warpfact * warpfact;
			time = Param.warptime * dist / (warpfact * warpfact);
			printf("Warp %.2f distance %.2f cost %.2f stardates %d (%d w/ shlds up) units\n",
				warpfact, dist, time, cost, cost + cost);
			break;

		  case 7:			/* impulse cost */
			dist = getfltpar("distance");
			if (dist < 0.0)
				break;
			cost = 20 + 100 * dist;
			time = dist / 0.095;
			printf("Distance %.2f cost %.2f stardates %d units\n",
				dist, time, cost);
			break;

		  case 8:			/* distresslist */
			j = 1;
			printf("\n");
			/* scan the event list */
			for (i = 0; i < MAXEVENTS; i++)
			{
				e = &Event[i];
				/* ignore hidden entries */
				if (e->evcode & E_HIDDEN)
					continue;
				switch (e->evcode & E_EVENT)
				{

				  case E_KDESB:
					printf("Klingon is attacking starbase in quadrant %d,%d\n",
						e->x, e->y);
					j = 0;
					break;

				  case E_ENSLV:
				  case E_REPRO:
					printf("Starsystem %s in quadrant %d,%d is distressed\n",
						Systemname[e->systemname], e->x, e->y);
					j = 0;
					break;
				}
			}
			if (j)
				printf("No known distress calls are active\n");
			break;

		}

		/* skip to next semicolon or newline.  Semicolon
		 * means get new computer request; newline means
		 * exit computer mode. */
		while ((i = cgetc(0)) != ';')
		{
			if (i == '\0')
				exit(1);
			if (i == '\n')
			{
				ungetc(i, stdin);
				return;
			}
		}
	}
}