[net.sources.games] UFO

kyrimis@tilt.FUN (Kriton Kyrimis) (09/21/85)

*** REPLACE THIS LINE WITH YOUR MESSAGE ***
Here's an (I hope) interesting little game I wrote way back when I was
learning how to program. People seem to like it, so I usually port it to
whatever environment I happen to be working in.

Typing "help" (or any reasonable abbreviation) to the question on help, will
print out the instructions.

This is a beautified C version of the original program which was written in
BASIC so, please, don't send me any flames about style. The program should
compile without problems on a system supporting curses, using:
	cc -O -s -o ufo ufo.c -lm -lcurses -ltermcap
Be sure to check the constant BIG at line 9, to see whether it needs to be
modified for your system.

If you decide to make any modifications (despite the bad programming style),
please send me a copy.

Have fun!
------------------------------CUT HERE----------------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	ufo.c
# This archive created: Sat Sep 21 01:04:30 1985
export PATH; PATH=/bin:$PATH
echo shar: extracting "'ufo.c'" '(7804 characters)'
if test -f 'ufo.c'
then
	echo shar: will not over-write existing file "'ufo.c'"
else
cat << \SHAR_EOF > 'ufo.c'
/* ufo.c
   By Kriton Kyrimis
   compile using:
	cc -O -s -o ufo ufo.c -lm -lcurses -ltermcap
*/
#include <curses.h>
#include <signal.h>

#define BIG 2147483648.0	/* max number returned by rand() plus 1 */

#define move_cursor(x,y)		\
		if( x<40 ){		\
			xx = COLS-1;	\
		}			\
		else{			\
			xx = 0;		\
		}			\
		if( y<12 ){		\
			yy = LINES-1;	\
		}			\
		else{			\
			yy = 0;		\
		}			\
		mvcur(yy, xx, (y), (x))

#define strip(s)					\
		while( (*s >= '0') && (*s <= '9') ){	\
			s++;				\
		}

int	ufos[51][3],
	field[21][76],
	num_ufos,
	missiles,
	missl_left,
	ufos_left,
	i,
	j,
	x,
	y,
	try,
	height,
	ht,
	top,
	bottom,
	left,
	right,
	ver,
	hor,
	xx,
	yy;
float	temp_score,
	mult,
	score_mult,
	grav,
	velocity,
	angle,
	init_height,
	tim;
	char inp[81],
	*inp1,
	*inp2,
	*bel,
	*bang[7],
	misl,
	*term,
	*back;

char *index(),*getenv();
int intr();
long time();
float rnd();
double atof(),fabs(),sqrt(),sin(),cos();

main()
{
	temp_score = 0.0;
	initialise();
	printf("%s",CL);
	move_cursor(0,LINES-1);
	help();
l35:
	printf("Enter number of UFOs (1-50): ");
	gets(inp);
	num_ufos = abs(atoi(inp));
	if( (num_ufos > 50) || (num_ufos < 1) ){
		printf("%s",bel);
		goto l35;
	}
	for(i=1; i<=num_ufos; i++){
l81:
		x = (int)(rnd()*16.0)+3;
		y = (int)(rnd()*65.0)+6;
		if( field[x][y] == 1 ){
			goto l81;
		}
		field[x][y] = 1;
		ufos[i][1] = x;
		ufos[i][2] = y;
	}
l115:
	printf("Enter number of missiles required (1-%d): ",2*num_ufos);
	gets(inp);
	missiles = abs(atoi(inp));
	if( (missiles>2*num_ufos) || (missiles<1) ){
		printf("%s",bel);
		goto l115;
	}
	mult = (float)missiles / (float)num_ufos;
	printf("Enter value of surface gravity in M/sec^2 <9.81>: ");
	gets(inp);
	grav = atof(inp) / 2.0;
	if( grav == 0.0 ){
		grav = 4.905; /* 9.81/2 */
	}
	printf("Enter Missile representation <*>: ");
	misl = getchar();
	if( misl == '\n' ){
		misl = '*';
	};
	printf("%s",CL);
	move_cursor(0, LINES-1);
	for(i=1; i<=20; i++){
		printf("|\n");
	}
	printf(
	"----------------------------------------------------------------------------"
	    );
	for(i=1; i<=num_ufos; i++){
		move_cursor(ufos[i][2],LINES-1-ufos[i][1]);
		putchar('#');
	}
	ufos_left = num_ufos;
	move_cursor(0,LINES-1);
	putchar('\n');
	for(try=1; try<=missiles; try++){
		move_cursor(0,LINES-1);
		if( try != 1 ){
			printf("%s",UP);
		}
l680:
		printf("Enter initial velocity, angle and height:\n");
		score_mult = (float)(try-1)/(float)missiles;
		missl_left = missiles-try+1;
		printf("Missiles left %d UFOs left %d Score %.0f x %5.3f          ",
		missl_left,ufos_left,temp_score,score_mult);
		goto l700;
l698:
		printf("%s%s",UP,bel);
		goto l680;
l700:
		move_cursor(42,LINES-2);
		gets(inp);
		inp1 = index(inp,',');
		inp2 = index(inp1+1,',');
		if( (inp1 == 0) || (inp2 == 0) ){
			goto l698;
		}
		velocity = atof(inp);
		angle = atof(inp1+1);
		init_height = atof(inp2+1);
		if( (angle < (float)0.0) ||
		    (angle >= (float)90.0) ||
		    (init_height > (float)19.0) ||
		    (init_height < (float)0.0) ||
		    (velocity > (float)sqrt((float)500.0 * fabs(grav))) ||
		    (velocity <= (float)0.0) ){
			goto l698;
		}
		temp_score += (velocity*velocity + 2*grav*height) * mult;
		height = (int)(init_height+0.5);
		angle = angle/180.0*3.1415926;
		move_cursor(1,LINES-4);
		if( height != 0 ){
			for(ht=1; ht<=height; ht++){
				printf("%s",UP);
			}
		}
		putchar(misl);
		for(x=1; x<=74; x++){
			tim = (float)x/(velocity*cos(angle));
			y = (int)(velocity*tim*sin(angle)-grav*tim*tim+0.5)+height;
			printf("%s",back);
			putchar(' ');
			if( y>19 ){
				goto l970;
			}
			else{
				if( y<0 ){
					goto l950;
				}
			}
			move_cursor(x+1,LINES-4-y);
			putchar(misl);
			if( field[y+1][x+1] == 0 ){
				goto l940;
			}
			bang[1] = ". . . . . .";
			bang[2] = " \\ | | | / ";
			bang[3] = ".- BANG! -.";
			bang[4] = " / | | | \\ ";
			bang[5] = ". . . . . .";
			bang[6] = "           ";
			printf("%s",bel);
			for(j=1; j<=5; j++){
				move_cursor(x-4,LINES-7-y+j);
				printf("%s%s%s%s",SO,bang[j],SE,DO);
			}
			for(j=1; j<=5; j++){
				move_cursor(x-4,LINES-7-y+j);
				printf("%s",bang[6]);
			}
			move_cursor(0,LINES-1);
			field[y+1][x+1] = 0;
			ufos_left -= 1;
			if( ufos_left == 0 ){
				goto l990;
			}
			check();
			if( ufos_left == 0 ){
				goto l990;
			}
			goto l980;
l940: 
			;
		}
		goto l970;
l950:
		printf("%s",bel);
		move_cursor(x-4,LINES-4);
		printf("( PLOUF! )");
		move_cursor(x-3,LINES-5);
		printf("^^^^^^^^");
		for(j=0; j<10000; j+=2){	/* wait a bit */
			j--;
		}
		move_cursor(x-4,LINES-4);
		printf("          ");
		move_cursor(x-3,LINES-5);
		printf("        ");
		move_cursor(0,LINES-1);
		goto l980;
l970:
		printf("%s%s ",bel,back);
l980: 
		;
	}
l990:
	printf("%s",CL);
	printf("Final score: %.0f\n\n",temp_score*score_mult);
	if( ufos_left == 0 ){
		printf("You have destroyed all %d UFOs using %d missiles.\n",num_ufos,try);
		printf("Congratulations !\n%s%s",VE,TE);
		resetty();
		exit(0);
	}
	printf("You are out of missiles,and there are still %d UFOs left.\n",ufos_left);
	printf("Instructions:\n");
	printf("A) Find the nearest trench.\n");
	printf("B) Fall in and lie down.\n");
	printf("C) Make sure you are fully covered.\n");
	printf("D) Cover your head with your hands.\n");
	printf("E) Kiss the world goodbye - ");
	printf("the UFOs are going to destroy the Earth, dummy! :-)\n%s%s",VE,TE);
	resetty();
}

initialise()
{
	srand(time());
	savetty();
	if( signal(SIGINT, SIG_IGN) != SIG_IGN ){
		signal(SIGINT, intr);
	}
	if( isatty(0) ){
		gettmode();
		if( (term=getenv("TERM")) ){
			setterm(term);
		}
		else{
			printf("Environment variable TERM is not defined.\n");
			resetty();
			exit(1);
		}
	}
	else{
		printf("Not a tty.\n");
		resetty();
		exit(1);
	}
	strip(TI);
	strip(TE);
	strip(VS);
	strip(VE);
	strip(VB);
	strip(CL);
	strip(SO);
	strip(SE);
	strip(BC);
	strip(UP);
	strip(DO);
	printf("%s",TI);
	printf("%s",VS);
	if( strlen(VB) != 0 ){
		bel = VB;
	}
	else{
		bel = "\007";
	}
	if( BS ){
		back = "\010";
	}
	else{
		back = BC;
	}
}

check()
{
	top = y-1;
	bottom = y+3;
	left = x-4;
	right = x+6;
	for(ver=top; ver<=bottom; ver++){
		for(hor=left; hor<=right; hor++){
			if( field[ver][hor] == 0 ){
				goto l3100;
			}
			field[ver][hor] = 0;
			ufos_left = ufos_left-1;
l3100: 
			;
		}
	}
}
help()
{
	printf("If you are not familiar with the game of UFO, ask for help: ");
	gets(inp);
	if( ! ((strcmp(inp,"help") 	== 0) 	|| (strcmp(inp,"HELP") == 0) ||
	    (strcmp(inp,"hel" ) 	== 0) 	|| (strcmp(inp,"HEL" ) == 0) ||
	    (strcmp(inp,"he"  ) 	== 0) 	|| (strcmp(inp,"HE" ) == 0) ||
	    (strcmp(inp,"h"   ) 	== 0) 	|| (strcmp(inp,"H" ) == 0)) ){
		return;
	}
	printf("\n\nYou are in charge of the UFO defence command:\n\n");
	printf(
	"You  have a gun that fires missiles in a gravity field.  To fire,you must enter\n");
	printf(
	"the  initial  velocity  of  the missile,  the  angle of the gun, as well as its\n");
	printf(
	"vertical  position.  These  data  must  be  given  in the aforementioned order,\n");
	printf("separated by commas.\n\n");
	printf(
	"Each  time you are asked to fire, you are given a graphic representation of the\n");
	printf(
	"field.  Each  axis  division stands for 1 metre.  As you are soon going to find\n");
	printf(
	"out,  the vertical scale is not equal to the horizontal one, so the angles seem\n");
	printf(
	"distorted.  However, this is your problem, and not mine.\n\n");
	printf(
	"Your  score  will  be  based  on many factors, and the lower it is, the better.\n");
	printf(
	"(Scores obtained from games with a different number of UFOs are not comparable)\n\n");
	printf("%sG O O D   L U C K !%s%s\n\n",SO,SE,bel);
}

float
rnd(x)
int x;
{
	return ( (float)rand() / BIG);
}

intr()
{
	move_cursor(0,LINES-1);
	printf("\n%sCoward!!!%s%s%s\n",SO,SE,VE,TE);
	resetty();
	exit(1);
}
SHAR_EOF
if test 7804 -ne "`wc -c < 'ufo.c'`"
then
	echo shar: error transmitting "'ufo.c'" '(should have been 7804 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0
-- 

	Kriton	(princeton!tilt!kyrimis)
------
"I reversed the polarity of the neutron flow..."
------