home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / games / volume15 / ufo / part01 / ufo.c < prev   
C/C++ Source or Header  |  1993-01-27  |  11KB  |  437 lines

  1.  
  2. #include <stdio.h>
  3. #include <curses.h>
  4. #include <string.h>
  5. #include <signal.h>
  6. #include <sys/types.h>
  7. #include <sys/time.h>
  8. #include <sys/timeb.h>
  9. #include <fcntl.h>
  10.  
  11. #define RAND_MAX 077777
  12. #define INF 03777777777
  13. #define MAX_TORS 25
  14.  
  15. /******************************************
  16.  *    To compile use a standard_C compiler
  17.  *  cc filename -lcurses -ltermcap; a.out  *
  18.  *    To run use 
  19.  *  a.out -T 200 -D 4 -N 4
  20.  *    T in ms tells how frequently ufo moves
  21.  *    D in characters tells how far the ufo
  22.         can hop
  23.  *    N Speed of the torpedos as a multiple of 
  24.         the plane speed
  25. *********************************************/
  26.  
  27. int T = 700000,
  28.     D = 5,
  29.     N=9;
  30.  
  31. int nxt_ufo_alarm = 100000,
  32.      nxt_plane_alarm=100000,
  33.     nxt_tor_alarm=INF,
  34.     nxt_int_alarm=INF,
  35.     NO_ACTIVITY=INF,
  36.     state_ufo=0;
  37.  
  38. int slowt[] ={1,1,2},
  39.     slowd[]={1,2,2};
  40.  
  41. char pch[]={'^','>','V','<'},
  42.     *ufostr[]={"UFOOFU",
  43.         "UF  FO",
  44.         "U     "};
  45.  
  46. char BELL[] = {7, 7, 0};
  47.  
  48. int pspeed, /* How many micro second per move */
  49.     pchidx = 0; /* direction of the plane */
  50.  
  51. int px, py, ux, uy;
  52.  
  53. struct tor { /* torpedos  */
  54.       int tspeed;  /* How much time before next position */
  55.       int tdir; /* Direction of travel */
  56.       int talarm; /* When is the next alarm due */
  57.       int x; /* X cordinate */
  58.       int y; /* y cordinate */
  59. } torpedo [MAX_TORS];
  60. int active = -1; /* Number of active torpedo */
  61.  
  62.  
  63.  
  64. WINDOW *ufo, *msg;
  65.  
  66. long big_bang;  
  67. struct timeb mytime;  /* Since Jan. 1, 1971  */
  68.  
  69. void alarm_ufo (int);
  70. void alarm_plane (int);
  71. void alarm_torpedo (int);
  72. void alarm_interrupt (int);
  73. void over (int);
  74.  
  75. void show(int now, int next_show) { 
  76.     static int last_show =0;
  77.     static int last_clear = 0;
  78.  
  79.     int i=-1;
  80.  
  81.     if ((next_show - last_show)< 30000) /* Too close */
  82.         return; /* Do not show */
  83.     last_show = now;
  84.     while (i++<active)
  85.         mvaddch(torpedo[i].y,torpedo[i].x,'*');
  86.     overlay(ufo,stdscr);
  87.     mvaddch(py,px,pch[pchidx]);
  88.     mvwprintw(msg, 0, 0, " %3d", 100-now/1000000); 
  89.      overlay(msg, stdscr); 
  90.     refresh();
  91.     if ((now-last_clear)>9000000) {  /* clear screen every 9 sec. */
  92.         last_clear = now;
  93.         clear();
  94.     }
  95.     else erase();
  96. }
  97.  
  98.  
  99. int find_time () {
  100.     struct timeb now;
  101.     ftime(&now);
  102.     return (1000*(now.time-big_bang)+ now.millitm)*1000;
  103. }
  104.  
  105.  
  106. void nxt_sched(void) {
  107.     /* Determine who is due for change of position
  108.         next. Is the change overdue? If yes
  109.         then do not waste time in refresh().
  110.         Hurry and get the change now.
  111.     */
  112.     
  113.     int alarm = nxt_plane_alarm;
  114.     int now;
  115.  
  116.         signal(SIGALRM, alarm_plane);
  117.         if (nxt_ufo_alarm<alarm) {
  118.             signal(SIGALRM, alarm_ufo);
  119.             alarm = nxt_ufo_alarm;
  120.         }
  121.                 if (nxt_int_alarm<alarm) {
  122.                         signal(SIGALRM, alarm_interrupt);
  123.                         alarm = nxt_int_alarm;
  124.                 }
  125.         if (active>-1)
  126.                     if (nxt_tor_alarm<alarm) {
  127.                             signal(SIGALRM, alarm_torpedo);
  128.                             alarm = nxt_tor_alarm;
  129.                     }
  130.  
  131.         now = find_time();
  132.         if (now>=alarm)
  133.             raise(SIGALRM); 
  134.         else {ualarm(alarm-now,0);
  135.                 show(now, alarm);
  136.         }
  137.     if ((now>100000000) || (now>NO_ACTIVITY))
  138.          signal(SIGALRM, over); 
  139. }
  140.     
  141.  
  142. int in_ufo(int y, int x) {/* Is the position in UFO */
  143.     /* Torpedo ready to damage */
  144.     switch (state_ufo) {
  145.     case 0:
  146.         if ((x>=ux) && (x<(ux+3)) && (y>=uy) && (y<(uy+2)))
  147.             return 1;
  148.         else return 0;
  149.     case 1: if ((x==ux) && (y==uy)) return 1;
  150.         if ((x==(ux+2)) && (y==(uy+1))) return 1;
  151.         if ((x==(ux+1)) && (y>=uy) && (y<(uy+2))) return 1;
  152.         return 0;
  153.     case 2: if ((x==ux) && (y==uy)) return 1;
  154.         return 0;
  155.     }
  156. }
  157.  
  158. int sitting_duck(void) {
  159.     /* Is the new position too bad for ufo */
  160.     if (in_ufo(py, px)) return 1;
  161.  
  162.     switch (pchidx) {
  163.         case 0: if (uy > py) return 0;
  164.             if (px < ux) return 0;
  165.             if (px > (ux+2)) return 0;
  166.             return 1;
  167.                 case 1: if ((2+ux) < px) return 0;
  168.                         if (py < uy) return 0;
  169.                         if (py > (uy+1)) return 0;
  170.                         return 1;  
  171.                 case 2: if ((uy+1) < py) return 0;
  172.                         if (px < ux) return 0;
  173.                         if (px > (ux+2)) return 0;
  174.                         return 1;
  175.                 case 3: if (ux > px) return 0;
  176.                         if (py < uy) return 0;
  177.                         if (py > (uy+1)) return 0;
  178.                         return 1;
  179.     }
  180. }
  181.  
  182. void over(int sig) {/* Game is over  */
  183.     signal(SIGINT, SIG_IGN);
  184.     nocbreak(); echo();
  185.     unlink("____tmp.c");
  186.         endwin();
  187.     printf("\n\nYour rating as a fighter pilot is:%d",state_ufo*
  188.                  (3+(D*1000000/T)+1000*1000000/find_time()));
  189.     printf("\nAdvise: Please avoid wars.\n");
  190.     exit();
  191. }
  192.  
  193. void alarm_ufo(int sig) { /* Reposition the ufo */
  194.     int oldx=ux, oldy=uy;
  195.     int d, x, y, a;
  196.     nxt_ufo_alarm += T/slowt[state_ufo];
  197.     d= D*rand()/RAND_MAX/slowd[state_ufo];
  198.     x= rand()-RAND_MAX/2; 
  199.     y= rand()-RAND_MAX/2;
  200.     a = abs(x)+abs(y);
  201.     ux = d*x/a+ux;
  202.     uy = d*y/a+uy;
  203.     if (ux<0) ux = -ux;
  204.     if (uy<0) uy = -uy;
  205.     if (ux>(COLS-3)) ux = 2*COLS-3-ux;
  206.     if (uy>(LINES-2)) uy = 2*LINES-2-uy;
  207.     /* Try to avoid plane, if possible */
  208.     if (sitting_duck())  {
  209.         switch (pchidx)  {
  210.             case 0: 
  211.             case 2:
  212.                 ux = oldx - 
  213.                     ((ux>(COLS/2))?D:-D)/slowd[state_ufo];
  214.                 if (ux<0) ux =0;
  215.                 uy = oldy;
  216.                 if (sitting_duck()) {
  217.                     ux = oldx + 
  218.                       ((ux>(COLS/2))?D:-D)/slowd[state_ufo];
  219.                     if (ux>(COLS-3)) ux = COLS -3;
  220.                 }
  221.                 break;
  222.                         case 1: 
  223.             case 3:
  224.                                 uy = oldy - 
  225.                     ((uy>(LINES/2))?D:-D)/slowd[state_ufo];
  226.                                 if (uy<0) uy =0;
  227.                                 ux = oldx;
  228.                                 if (sitting_duck()) {
  229.                                         uy = oldy +
  230.                      ((uy>(LINES/2))?D:-D)/slowd[state_ufo];
  231.                                         if (uy>(LINES-2)) uy = LINES -2;
  232.                                 }
  233.         }
  234.     }
  235.     mvwin(ufo, uy, ux);
  236.     nxt_ufo_alarm += T/slowt[state_ufo];
  237.     nxt_sched();
  238. }
  239.  
  240. void alarm_plane (int sig) { /* reposition the plane */
  241.     switch (pchidx) {
  242.         case 0: {py--; 
  243.              if (py<0) {
  244.                 py =0; pchidx =2;}
  245.              break;
  246.         }
  247.         case 1: {px++; 
  248.             if (px>=COLS) {
  249.                 px =COLS-1; pchidx=3;}
  250.             break;
  251.         }
  252.         case 2: {py++;
  253.             if (py>=LINES) {
  254.                 py=LINES-1; pchidx=0;}
  255.              break;
  256.         }
  257.         case 3: {px--;
  258.             if (px<0) {
  259.                 px=0; pchidx=1;}
  260.              break;
  261.         }
  262.     }
  263.     nxt_plane_alarm += pspeed;
  264.     nxt_sched();
  265. }
  266.  
  267.  
  268. void alarm_torpedo (int sig) { 
  269.     /* Assumption is that no more then 10 torpedos are in 
  270.     action at a time 
  271.     */
  272.  
  273.     int now = find_time();
  274.  
  275.     int first, i;
  276.     int mask;
  277.  
  278.     mask = sigblock(sigmask(SIGINT));
  279.     i = -1; first = i;
  280.     while (++i<=active) {
  281.         if (torpedo[i].talarm<now) {
  282.             /*mvaddch(torpedo[i].y, torpedo[i].x,' ');*/
  283.             torpedo[i].talarm += torpedo[i].tspeed;
  284.             switch (torpedo[i].tdir) {
  285.             case 0: {torpedo[i].y -= 1;
  286.                 if (torpedo[i].y<0)
  287.                     torpedo[i]=torpedo[active--];
  288.                 break;
  289.             }
  290.                         case 1: {torpedo[i].x += 1;
  291.                                 if (torpedo[i].x>COLS)
  292.                                         torpedo[i]=torpedo[active--];
  293.                 break;
  294.                         }
  295.                         case 2: {torpedo[i].y += 1;
  296.                                 if (torpedo[i].y>LINES)
  297.                                         torpedo[i]=torpedo[active--];
  298.                 break;
  299.                         }
  300.                         case 3: {torpedo[i].x -= 1;
  301.                                 if (torpedo[i].x<0)
  302.                                         torpedo[i]=torpedo[active--];
  303.                 break;
  304.                         }
  305.             }
  306.             if (in_ufo(torpedo[i].y, torpedo[i].x)) {
  307.                 if (state_ufo++==2) over(0);
  308.                 addstr(BELL); refresh();
  309.                 mvwaddstr(ufo,0,0,ufostr[state_ufo]);
  310.                 torpedo[i] = torpedo[active--];
  311.             } 
  312.         }
  313.         /*mvaddch(torpedo[i].y, torpedo[i].x,'*');*/
  314.         if (first==-1) first = i;
  315.         if (torpedo[i].talarm<torpedo[first].talarm)
  316.             first =i;
  317.     }
  318.     nxt_tor_alarm = torpedo[first].talarm;
  319.     sigsetmask(mask);
  320.     nxt_sched();
  321. }
  322.  
  323.     
  324. void fire (int sig) { /* Fire a torpedo */
  325.     NO_ACTIVITY = 20000000+ find_time();
  326.     if (active >= (MAX_TORS-1)) return; /* Too many torpedos */
  327.     signal(SIGINT, SIG_IGN);
  328.     ualarm(0,0);
  329.     nxt_int_alarm = find_time()+T;
  330.     active++;
  331.     torpedo[active].x = px;
  332.         torpedo[active].y = py;
  333.         torpedo[active].tspeed = pspeed/N;
  334.     torpedo[active].talarm =find_time()+pspeed/N;
  335.     torpedo[active].tdir = pchidx;
  336.     if (torpedo[active].talarm<nxt_tor_alarm)
  337.         nxt_tor_alarm = torpedo[active].talarm;
  338.     mvaddch(torpedo[active].y, torpedo[active].x,'#');
  339.     nxt_sched(); 
  340. }
  341.  
  342.  
  343. void alarm_interrupt(int sig) { /* Set up the gun */
  344.     NO_ACTIVITY = 20000000+ find_time();
  345.     nxt_int_alarm = INF;
  346.     signal(SIGINT, fire);
  347.     nxt_sched();
  348. }
  349.  
  350. main (int argc, char *argv[]) {
  351.     int t, mask;
  352.     char cmd;
  353.     
  354.     /* Read command line parameters  */
  355.     t =1;
  356.     while (argc>1) {
  357.         if (!strcmp(argv[t],"-T"))
  358.             T=atoi(argv[t+1])*1000;
  359.         if (!strcmp(argv[t],"-D"))
  360.             D=atoi(argv[t+1]);
  361.         if (!strcmp(argv[t],"-N"))
  362.                         N=atoi(argv[t+1]);
  363.         t +=2; argc -=2;
  364.     }
  365.     printf("\n\n   Input        Effect\n");
  366.     printf("    a or A    Accelerate the plane 25%%\n");
  367.     printf("cntl-c, c or C    Fire a torpedo\n");
  368.     printf("    d or D    Decelerate the plane 20%%\n");
  369.     printf("<, >, ^, v or V    Turn the plane as specified\n");
  370.     printf("j, l, i, k    Same as the line above\n");
  371.     printf("J, L, I, K    Same as the line above\n");
  372.     printf("    - or _    Turn plane clockwise\n");
  373.     printf("    + or =    Turn plane anticlockwise\n");
  374.     printf("    s or S  Stops the game\n");
  375.     printf("\n\n    Runs for 100 seconds only\n");
  376.     printf("    Stops if no activity for 20 seconds.\n");
  377.  
  378. /* To detect unauthorised players */
  379.     sleep(2);
  380.     ftime(&mytime);
  381.     big_bang = mytime.time;
  382.     initscr();
  383.     refresh();
  384.     msg = newwin(1,COLS,LINES-1,0);
  385.     ufo = newwin(2,3,0,0);
  386.     cbreak(); noecho(); 
  387.     clear();
  388.     signal(SIGINT, fire);
  389.     waddstr(ufo,ufostr[0]);
  390.     px = COLS/2; py = LINES/2;
  391.     pspeed = T/D;
  392.     ux = 0; uy = 0;
  393.     nxt_sched();    
  394.     NO_ACTIVITY = 20000000+ find_time();
  395.     while((cmd=getch()) != 's') {int oldspeed;
  396.         /* Avoid any interference  */
  397.         mask=sigblock(sigmask(SIGINT));
  398.         ualarm(0,0);  
  399.         oldspeed =pspeed;
  400.         switch (cmd) {
  401.             case '=':
  402.             case '+': {pchidx = (pchidx+1)%4;
  403.                     break;
  404.             }
  405.             case '_':
  406.             case '-': {pchidx = (pchidx+3)%4;
  407.                     break;
  408.             }
  409.             case 'D':
  410.             case 'd': {pspeed *= 1.25;
  411.                     break;
  412.             }
  413.             case 'A':
  414.             case 'a': pspeed *= 0.8; break;
  415.             case 'c':
  416.             case 'C': raise(SIGINT); break;
  417.             case '<': case 'j': case 'J':
  418.             case ',': pchidx = 3; break;
  419.             case '>': case 'l': case 'L':
  420.             case '.': pchidx = 1; break;
  421.             case '6': case 'i': case 'I':
  422.             case '^': pchidx = 0; break;
  423.             case 'V': case 'k': case 'K':
  424.             case 'v': pchidx = 2; break;
  425.             default:;
  426.         }
  427.         NO_ACTIVITY = 20000000+ find_time();
  428.         nxt_plane_alarm += pspeed -oldspeed;
  429.         sigsetmask(mask);
  430.         nxt_sched();
  431.     }
  432.     nocbreak(); echo();
  433.     endwin();
  434.     unlink("____tmp.c");
  435. }
  436.  
  437.