home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
games
/
volume15
/
ufo
/
part01
/
ufo.c
< prev
Wrap
C/C++ Source or Header
|
1993-01-27
|
11KB
|
437 lines
#include <stdio.h>
#include <curses.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <fcntl.h>
#define RAND_MAX 077777
#define INF 03777777777
#define MAX_TORS 25
/******************************************
* To compile use a standard_C compiler
* cc filename -lcurses -ltermcap; a.out *
* To run use
* a.out -T 200 -D 4 -N 4
* T in ms tells how frequently ufo moves
* D in characters tells how far the ufo
can hop
* N Speed of the torpedos as a multiple of
the plane speed
*********************************************/
int T = 700000,
D = 5,
N=9;
int nxt_ufo_alarm = 100000,
nxt_plane_alarm=100000,
nxt_tor_alarm=INF,
nxt_int_alarm=INF,
NO_ACTIVITY=INF,
state_ufo=0;
int slowt[] ={1,1,2},
slowd[]={1,2,2};
char pch[]={'^','>','V','<'},
*ufostr[]={"UFOOFU",
"UF FO",
"U "};
char BELL[] = {7, 7, 0};
int pspeed, /* How many micro second per move */
pchidx = 0; /* direction of the plane */
int px, py, ux, uy;
struct tor { /* torpedos */
int tspeed; /* How much time before next position */
int tdir; /* Direction of travel */
int talarm; /* When is the next alarm due */
int x; /* X cordinate */
int y; /* y cordinate */
} torpedo [MAX_TORS];
int active = -1; /* Number of active torpedo */
WINDOW *ufo, *msg;
long big_bang;
struct timeb mytime; /* Since Jan. 1, 1971 */
void alarm_ufo (int);
void alarm_plane (int);
void alarm_torpedo (int);
void alarm_interrupt (int);
void over (int);
void show(int now, int next_show) {
static int last_show =0;
static int last_clear = 0;
int i=-1;
if ((next_show - last_show)< 30000) /* Too close */
return; /* Do not show */
last_show = now;
while (i++<active)
mvaddch(torpedo[i].y,torpedo[i].x,'*');
overlay(ufo,stdscr);
mvaddch(py,px,pch[pchidx]);
mvwprintw(msg, 0, 0, " %3d", 100-now/1000000);
overlay(msg, stdscr);
refresh();
if ((now-last_clear)>9000000) { /* clear screen every 9 sec. */
last_clear = now;
clear();
}
else erase();
}
int find_time () {
struct timeb now;
ftime(&now);
return (1000*(now.time-big_bang)+ now.millitm)*1000;
}
void nxt_sched(void) {
/* Determine who is due for change of position
next. Is the change overdue? If yes
then do not waste time in refresh().
Hurry and get the change now.
*/
int alarm = nxt_plane_alarm;
int now;
signal(SIGALRM, alarm_plane);
if (nxt_ufo_alarm<alarm) {
signal(SIGALRM, alarm_ufo);
alarm = nxt_ufo_alarm;
}
if (nxt_int_alarm<alarm) {
signal(SIGALRM, alarm_interrupt);
alarm = nxt_int_alarm;
}
if (active>-1)
if (nxt_tor_alarm<alarm) {
signal(SIGALRM, alarm_torpedo);
alarm = nxt_tor_alarm;
}
now = find_time();
if (now>=alarm)
raise(SIGALRM);
else {ualarm(alarm-now,0);
show(now, alarm);
}
if ((now>100000000) || (now>NO_ACTIVITY))
signal(SIGALRM, over);
}
int in_ufo(int y, int x) {/* Is the position in UFO */
/* Torpedo ready to damage */
switch (state_ufo) {
case 0:
if ((x>=ux) && (x<(ux+3)) && (y>=uy) && (y<(uy+2)))
return 1;
else return 0;
case 1: if ((x==ux) && (y==uy)) return 1;
if ((x==(ux+2)) && (y==(uy+1))) return 1;
if ((x==(ux+1)) && (y>=uy) && (y<(uy+2))) return 1;
return 0;
case 2: if ((x==ux) && (y==uy)) return 1;
return 0;
}
}
int sitting_duck(void) {
/* Is the new position too bad for ufo */
if (in_ufo(py, px)) return 1;
switch (pchidx) {
case 0: if (uy > py) return 0;
if (px < ux) return 0;
if (px > (ux+2)) return 0;
return 1;
case 1: if ((2+ux) < px) return 0;
if (py < uy) return 0;
if (py > (uy+1)) return 0;
return 1;
case 2: if ((uy+1) < py) return 0;
if (px < ux) return 0;
if (px > (ux+2)) return 0;
return 1;
case 3: if (ux > px) return 0;
if (py < uy) return 0;
if (py > (uy+1)) return 0;
return 1;
}
}
void over(int sig) {/* Game is over */
signal(SIGINT, SIG_IGN);
nocbreak(); echo();
unlink("____tmp.c");
endwin();
printf("\n\nYour rating as a fighter pilot is:%d",state_ufo*
(3+(D*1000000/T)+1000*1000000/find_time()));
printf("\nAdvise: Please avoid wars.\n");
exit();
}
void alarm_ufo(int sig) { /* Reposition the ufo */
int oldx=ux, oldy=uy;
int d, x, y, a;
nxt_ufo_alarm += T/slowt[state_ufo];
d= D*rand()/RAND_MAX/slowd[state_ufo];
x= rand()-RAND_MAX/2;
y= rand()-RAND_MAX/2;
a = abs(x)+abs(y);
ux = d*x/a+ux;
uy = d*y/a+uy;
if (ux<0) ux = -ux;
if (uy<0) uy = -uy;
if (ux>(COLS-3)) ux = 2*COLS-3-ux;
if (uy>(LINES-2)) uy = 2*LINES-2-uy;
/* Try to avoid plane, if possible */
if (sitting_duck()) {
switch (pchidx) {
case 0:
case 2:
ux = oldx -
((ux>(COLS/2))?D:-D)/slowd[state_ufo];
if (ux<0) ux =0;
uy = oldy;
if (sitting_duck()) {
ux = oldx +
((ux>(COLS/2))?D:-D)/slowd[state_ufo];
if (ux>(COLS-3)) ux = COLS -3;
}
break;
case 1:
case 3:
uy = oldy -
((uy>(LINES/2))?D:-D)/slowd[state_ufo];
if (uy<0) uy =0;
ux = oldx;
if (sitting_duck()) {
uy = oldy +
((uy>(LINES/2))?D:-D)/slowd[state_ufo];
if (uy>(LINES-2)) uy = LINES -2;
}
}
}
mvwin(ufo, uy, ux);
nxt_ufo_alarm += T/slowt[state_ufo];
nxt_sched();
}
void alarm_plane (int sig) { /* reposition the plane */
switch (pchidx) {
case 0: {py--;
if (py<0) {
py =0; pchidx =2;}
break;
}
case 1: {px++;
if (px>=COLS) {
px =COLS-1; pchidx=3;}
break;
}
case 2: {py++;
if (py>=LINES) {
py=LINES-1; pchidx=0;}
break;
}
case 3: {px--;
if (px<0) {
px=0; pchidx=1;}
break;
}
}
nxt_plane_alarm += pspeed;
nxt_sched();
}
void alarm_torpedo (int sig) {
/* Assumption is that no more then 10 torpedos are in
action at a time
*/
int now = find_time();
int first, i;
int mask;
mask = sigblock(sigmask(SIGINT));
i = -1; first = i;
while (++i<=active) {
if (torpedo[i].talarm<now) {
/*mvaddch(torpedo[i].y, torpedo[i].x,' ');*/
torpedo[i].talarm += torpedo[i].tspeed;
switch (torpedo[i].tdir) {
case 0: {torpedo[i].y -= 1;
if (torpedo[i].y<0)
torpedo[i]=torpedo[active--];
break;
}
case 1: {torpedo[i].x += 1;
if (torpedo[i].x>COLS)
torpedo[i]=torpedo[active--];
break;
}
case 2: {torpedo[i].y += 1;
if (torpedo[i].y>LINES)
torpedo[i]=torpedo[active--];
break;
}
case 3: {torpedo[i].x -= 1;
if (torpedo[i].x<0)
torpedo[i]=torpedo[active--];
break;
}
}
if (in_ufo(torpedo[i].y, torpedo[i].x)) {
if (state_ufo++==2) over(0);
addstr(BELL); refresh();
mvwaddstr(ufo,0,0,ufostr[state_ufo]);
torpedo[i] = torpedo[active--];
}
}
/*mvaddch(torpedo[i].y, torpedo[i].x,'*');*/
if (first==-1) first = i;
if (torpedo[i].talarm<torpedo[first].talarm)
first =i;
}
nxt_tor_alarm = torpedo[first].talarm;
sigsetmask(mask);
nxt_sched();
}
void fire (int sig) { /* Fire a torpedo */
NO_ACTIVITY = 20000000+ find_time();
if (active >= (MAX_TORS-1)) return; /* Too many torpedos */
signal(SIGINT, SIG_IGN);
ualarm(0,0);
nxt_int_alarm = find_time()+T;
active++;
torpedo[active].x = px;
torpedo[active].y = py;
torpedo[active].tspeed = pspeed/N;
torpedo[active].talarm =find_time()+pspeed/N;
torpedo[active].tdir = pchidx;
if (torpedo[active].talarm<nxt_tor_alarm)
nxt_tor_alarm = torpedo[active].talarm;
mvaddch(torpedo[active].y, torpedo[active].x,'#');
nxt_sched();
}
void alarm_interrupt(int sig) { /* Set up the gun */
NO_ACTIVITY = 20000000+ find_time();
nxt_int_alarm = INF;
signal(SIGINT, fire);
nxt_sched();
}
main (int argc, char *argv[]) {
int t, mask;
char cmd;
/* Read command line parameters */
t =1;
while (argc>1) {
if (!strcmp(argv[t],"-T"))
T=atoi(argv[t+1])*1000;
if (!strcmp(argv[t],"-D"))
D=atoi(argv[t+1]);
if (!strcmp(argv[t],"-N"))
N=atoi(argv[t+1]);
t +=2; argc -=2;
}
printf("\n\n Input Effect\n");
printf(" a or A Accelerate the plane 25%%\n");
printf("cntl-c, c or C Fire a torpedo\n");
printf(" d or D Decelerate the plane 20%%\n");
printf("<, >, ^, v or V Turn the plane as specified\n");
printf("j, l, i, k Same as the line above\n");
printf("J, L, I, K Same as the line above\n");
printf(" - or _ Turn plane clockwise\n");
printf(" + or = Turn plane anticlockwise\n");
printf(" s or S Stops the game\n");
printf("\n\n Runs for 100 seconds only\n");
printf(" Stops if no activity for 20 seconds.\n");
/* To detect unauthorised players */
sleep(2);
ftime(&mytime);
big_bang = mytime.time;
initscr();
refresh();
msg = newwin(1,COLS,LINES-1,0);
ufo = newwin(2,3,0,0);
cbreak(); noecho();
clear();
signal(SIGINT, fire);
waddstr(ufo,ufostr[0]);
px = COLS/2; py = LINES/2;
pspeed = T/D;
ux = 0; uy = 0;
nxt_sched();
NO_ACTIVITY = 20000000+ find_time();
while((cmd=getch()) != 's') {int oldspeed;
/* Avoid any interference */
mask=sigblock(sigmask(SIGINT));
ualarm(0,0);
oldspeed =pspeed;
switch (cmd) {
case '=':
case '+': {pchidx = (pchidx+1)%4;
break;
}
case '_':
case '-': {pchidx = (pchidx+3)%4;
break;
}
case 'D':
case 'd': {pspeed *= 1.25;
break;
}
case 'A':
case 'a': pspeed *= 0.8; break;
case 'c':
case 'C': raise(SIGINT); break;
case '<': case 'j': case 'J':
case ',': pchidx = 3; break;
case '>': case 'l': case 'L':
case '.': pchidx = 1; break;
case '6': case 'i': case 'I':
case '^': pchidx = 0; break;
case 'V': case 'k': case 'K':
case 'v': pchidx = 2; break;
default:;
}
NO_ACTIVITY = 20000000+ find_time();
nxt_plane_alarm += pspeed -oldspeed;
sigsetmask(mask);
nxt_sched();
}
nocbreak(); echo();
endwin();
unlink("____tmp.c");
}