⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bugs.c

📁 该程序是C语言编写的
💻 C
字号:
/*----------------------------------------------------*- Fundamental -*-

Facility:		bugs(6)

File:			bugs.c

Associated files:	- (none)

Description:		Bugs me. Bugs anyone.

Notes:			Needs curses.

Author:			Steve Ward

Editor:			Anders Thulin
			Rydsvagen 288
			S-582 50 Linkoping
			SWEDEN

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

Edit history :

Vers  Ed   Date	       By                Comments
----  ---  ----------  ----------------  -------------------------------
 1.0    0  19xx-xx-xx  Steve Ward
 1.1    1  1990-03-16  Anders Thulin     Changed H19/H89 screen handling to
				         curses. Still buggy, though :-)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

/*---  Configuration:  --------------------------------------------------

System configuration options:
=============================

  ANSI		ANSI C conformant compiler
  BSD		BSD Unix
  SYSV		AT&T System V.x Unix

If you have an ANSI compiler, defined ANSI only.  Otherwise, define
the alternative that most closely matches your environment.


Program configuration:
======================

  NBUGS		Max. number of bugs permitted


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#define	ANSI	 1
#define	BSD	 0
#define	SYSV	 0

#define	NBUGS	25

/* - - End of configurations - - - - - - - - - - - - - - - - - - - - - - - - */

#include <curses.h>
#include <stdio.h>

#if ANSI
# include <stdlib.h>
 extern int getopt(int argc, char **argv, char *optstring);
 extern int optind;
#endif

#if BSD
 extern int getopt();
 extern void exit();
 extern int optind;
# define EXIT_FAILURE   1
# define EXIT_SUCCESS	0
#endif

#if SYSV
 extern int getopt();
 extern void exit();
 extern int optind;
# define EXIT_FAILURE   1
# define EXIT_SUCCESS	0
#endif

#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif

/*----------------------------------------------------------------------

Known problems:

curses

  The program relies on non-blocking calls to getch() so that it can
  quit as soon as the `user' presses a key.  Older implementations of
  curses don't have the function nodelay() which sets up for nonblocking
  calls to getch().

  It may be possible to remove the calls to getch() altogether.
  Instead, catch SIGINT (or whatever is used to indicate that user
  wants to quit) to make an orderly exit from curses.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */


/*
	"Bugs"
	written by Steve Ward for the H19/H89 display terminal
	BD says..."This one is WIERD!!!"
*/

#define BOT	0
#define LEFT	0
#define RADIUS2	21

int	Top,		/* Pagesize-1				*/
	Right;		/* Linelength-2				*/

struct bug {
  int X,Y;
  int Dir;	/* 0-down, 1-left, 2-up, 3-right.	*/
  int State;
} bugs[NBUGS];

char	Wflg, Cflg;
int	CurX, CurY;
int	CBugs;

int XMotion[20] = { 0, 1, 0, -1,  1, 1, -1, -1};
int YMotion[20] = {-1, 0, 1,  0, -1, 1,  1, -1};

/* Q & D fix for placech():  */

#define placech(ch, tx, ty) 		\
	do {				\
	  mvaddch((ty), (tx), (ch));	\
	  refresh();			\
	} while (0)

/*----------------------------------------------------------------------
  Local functions:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#if __STDC__ != 0
 static int  alive(struct bug *bb);
 static void mkbug(struct *bb, int xp, int yp, int direc);
 static void r(struct bug *bb, int dx, int dy, int ch);
 static void randbug(struct bug *bb);
 static void step(struct bug *bb);
 static void turn(struct bug *bb);
#else
 static int  alive();
 static void mkbug();
 static void r();
 static void randbug();
 static void step();
 static void turn();
#endif

static int alive(bb)
struct bug *bb;
{
  int px,py;
  px = bb->X; py = bb->Y;
  switch((bb->Dir) & 03) {
    case 0: return(py>=BOT-4);
    case 1: return(px<=Right+6);
    case 2: return(py<=Top+4);
    case 3: return(px>=LEFT-4); 
  }
  /*NOTREACHED*/
}

static void step(bb)
struct bug *bb;
{
  switch ((*bb).State) {
    case 0: r(bb,1,0,' '); r(bb,1,-1,'\\'); (*bb).State++; break;
    case 1:	r(bb,-1,0,' ');
			r(bb,-1,-1,'/');
			(*bb).State++;	break;
    case 2:	r(bb,1,1,' ');
			r(bb,1,0,'\\');
			(*bb).State++;	break;
    case 3:	r(bb,-1,1,' ');
			r(bb,-1,0,'/');
			(*bb).State++;	break;
    case 4:	r(bb,0,-1,'0');
			r(bb,0,0,'O');
			r(bb,1,-1,'/');
			r(bb,-1,-1,'\\');
			r(bb,1,0,'/');
			r(bb,-1,0,'\\');
			(*bb).State++;	break;
    case 5:	r(bb,1,2,' ');
			r(bb,1,1,'\\');
			(*bb).State++;	break;
    case 6:	r(bb,-1,2,' ');
			r(bb,-1,1,'/');
			(*bb).State++;	break;
    case 7:	r(bb,1,1,'/');
			r(bb,0,1,' ');
			r(bb,-1,1,'\\');
			switch (((*bb).Dir) & 03) {
			 case 0: (*bb).Y--; break;
			 case 2: (*bb).Y++; break;
			 case 1: (*bb).X++; break;
			 case 3: (*bb).X--; break; }
			(*bb).State = 0;	break;
/* Diagonal movement:						*/

    case 20:	r(bb,1,1,' ');
			r(bb,1,0,'-');
			(*bb).State++;	break;
    case 21:	r(bb,-1,-1,' ');
			r(bb,0,-1,'|');
			(*bb).State++;	break;
    case 22:	r(bb,0,1,' ');
			r(bb,1,1,'/');
			(*bb).State++;	break;
    case 23:	r(bb,-1,0,' ');
			r(bb,-1,-1,'/');
			(*bb).State++;	break;
    case 24:	r(bb,1,-1,'0');
			r(bb,0,0,'O');
			r(bb,1,1,' ');
			r(bb,0,1,'|');
			r(bb,-1,-1,' ');
			r(bb,-1,0,'-');
			r(bb,1,0,'|');
			r(bb,0,-1,'-');
			(*bb).State++;	break;
    case 25:	r(bb,-1,2,' ');
			r(bb,0,2,'/');
			(*bb).State++;	break;
    case 26:	r(bb,-2,1,' ');
			r(bb,-2,0,'/');
			(*bb).State++;	break;
    case 27:	r(bb,-1,1,' ');
			r(bb,0,2,' ');
			r(bb,-2,0,' ');
			r(bb,1,0,'|');
			r(bb,0,-1,'-');
			switch (((*bb).Dir)& 03) {
			 case 0: (*bb).X++; (*bb).Y--; break;
			 case 1: (*bb).X++; (*bb).Y++; break;
			 case 2: (*bb).X--; (*bb).Y++; break;
			 case 3: (*bb).X--; (*bb).Y--; break; }
			(*bb).State = 20;	break;

/* turn from diag to orthogonal (45 deg CCW)				*/

    case 40:	r(bb,-1,0,' ');
			r(bb,-2,0,'/');
			(*bb).State++; break;
    case 41:	r(bb,-1,0,'O');
			r(bb,-1,2,' ');
			r(bb,-1,1,'|');
			r(bb,-2,0,'\\');
			r(bb,-2,1,'\\');
			(*bb).State++; break;
    case 42:	r(bb,1,1,' ');
			r(bb,0,1,'\\');
			r(bb,-1,1,'\\');
			r(bb,-2,0,' ');
			r(bb,-2,-1,'/');
			r(bb,0,-1,'/');
			(*bb).Dir = (((*bb).Dir)+1) & 03;
			(*bb).State = 0; break;

/* Turn from ortho to diagonal:					*/

    case 50:	r(bb,-1,0,' ');
			r(bb,-1,-1,'/');
			(*bb).State++; break;
    case 51:	r(bb,-1,1,' ');
			r(bb,-1,0,'/');
			(*bb).State++; break;
    case 52:	r(bb,1,2,' ');
			r(bb,0,1,'|');
			r(bb,-1,1,'O');
			r(bb,1,0,' ');
			r(bb,-1,2,' ');
			r(bb,0,2,'/');
			r(bb,-1,0,' ');
			r(bb,-2,0,'/');
			r(bb,-2,1,'-');
			(*bb).State++; break;
    case 53:	r(bb,0,2,' ');
			r(bb,-1,2,'|');
			r(bb,-2,0,' ');
			r(bb,-1,0,'-');
			(*bb).Dir = (((*bb).Dir) | 04);
			(*bb).State = 20; break;
  }
}

static void mkbug(bb, xp, yp, direc)
struct bug *bb;
int xp, yp, direc;
{
  bb->X = xp;
  bb->Y = yp;
  bb->State = 0;
  bb->Dir = direc;

  if (direc < 4) {
    r(bb,0,0,'0');
    r(bb,0,1,'O');
    r(bb,1,0,'/');
    r(bb,1,1,'/');
    r(bb,1,2,'/');
    r(bb,-1,2,'\\');
    r(bb,-1,1,'\\');
    r(bb,-1,0,'\\');
  } else {
    bb->State = 20;
    r(bb,0,0,'0');
    r(bb,1,1,'/');
    r(bb,-1,-1,'/');
    r(bb,0,1,'|');
    r(bb,-1,0,'-');
    r(bb,-1,1,'O');
    r(bb,-1,2,'|');
    r(bb,-2,1,'-');
  }
}


static void r(bb, dx, dy, ch)
struct bug *bb;
int         dx, dy;
char        ch;
{
  int tx, ty, direc;

  direc = (bb->Dir) & 03;
  if ((direc == 1) || (direc == 3)) {
    switch (ch) {
      case '/':	 ch = '\\'; break;
      case '\\': ch = '/'; break;
      case '|':	 ch = '-'; break;
      case '-':	 ch = '|'; break;
      default:	 break;
    }
  }

  switch (direc) {
    case 0: tx = dx+bb->X; ty = dy+bb->Y; break;
    case 2: tx = bb->X-dx; ty = bb->Y-dy; break;
    case 1: tx = bb->X-dy; ty = bb->Y+dx; break;
    case 3: tx = bb->X+dy; ty = bb->Y-dx; break;
  }
  placech(ch,tx,ty); 
}


static void randbug(bb)
struct bug *bb;
{
  int x,y,dir;
  dir = rand()%8;
  x = rand()%80;
  y = rand()%24;
  if (Cflg) {
    x = (Right-LEFT)/2;
    y = (Top-BOT)/2;
  } else switch(dir & 03) {
    case 0: y=24+4; break;
    case 2: y = -4; break;
    case 1: x = -4; break;
    case 3: x=80+4; break;
  }
  mkbug(bb,x,y,dir);
}

static void turn(bb)
struct bug *bb;
{
  if (bb->State == 0) {
    bb->State = 50;
  } else if (bb->State == 20) {
    bb->State = 40;
  }
  return;
}

int main(argc,argv)
int   argc;
char *argv[];
{
  int c;
  int errflg;
  int i,j,xdist,ydist,xmot,ymot;
  char *arg;

  CurX = 1000; CurY = 1000;
  Wflg = 0; Cflg = 0;
  CBugs = 5;

  errflg = 0;
  while ((c = getopt(argc, argv, "cCwW")) != EOF) {
    switch(c) {
      case '?':
        errflg = 1;
        break;

      case 'c':
      case 'C':
        Cflg++;
        break;

      case 'w':
      case 'W' :
        Wflg++;
        break;
    }
  }

  if (optind < argc) {
    CBugs = atoi(argv[optind++]);
  }
  if (optind < argc) {
    fprintf(stderr, "error: unexpected argument '%s'\n", argv[optind]);
    errflg = 1;
  }
  if (errflg != 0) {
    fprintf(stderr, "usage: [-c] [-w] [nr_of_bugs]\n");
    exit(EXIT_FAILURE);
  }

  if (CBugs>NBUGS) CBugs=NBUGS;

  initscr();
  noecho();
  nodelay(stdscr, TRUE);
  cbreak();
  clear();
  Top = LINES-1; Right = COLS-2;  

  if (Wflg) {
    for (i=LEFT; i<Right; i++) placech('-',i,Top);
    for (i=Top; i>BOT; i--) placech('|',Right,i);
    for (i=LEFT; i<Right; i++) placech('-',i,BOT);
    for (i=Top; i>BOT; i--) placech('|',LEFT,i);
  }

  for (i=0; i<CBugs; i++) {
    randbug(&bugs[i]);
  }

  /*  3.  Bug!  */

  for (;;) {

    /*  Had enough?  */

    if (getch() != ERR) {	/* Key hit - quit */
      break;
    }

    i = rand() % CBugs;
    if (!alive(&bugs[i])) {
      randbug(&bugs[i]);
    } else {
      step(&bugs[i]);
      j = (bugs[i]).State;
      xmot = XMotion[(bugs[i]).Dir];
      ymot = YMotion[(bugs[i]).Dir];
      if ((j == 0) || (j == 20)) {
        if (Wflg) {
	  xdist = (bugs[i]).X;
	  ydist = xdist-Right;
	  if ((xmot>0) && (ydist<0) && (ydist*ydist < RADIUS2))
	    turn(&bugs[i]);
	  ydist = xdist-LEFT;
	  if ((xmot<0)&&(ydist>0) && (ydist*ydist < RADIUS2))
	    turn(&bugs[i]);
	  xdist = (bugs[i]).Y;
	  ydist = xdist-Top;
	  if ((ymot>0)&&(ydist<0) && (ydist*ydist < RADIUS2))
	    turn(&bugs[i]);
	  ydist = xdist-BOT;
	  if ((ymot<0)&&(ydist>0) && (ydist*ydist < RADIUS2))
	    turn(&bugs[i]);
        }
      }

      if ((j == 0) || (j == 20)) {
        for (j=0;j<CBugs;j++) {
          if (j==i)
            continue;
	  xdist = (bugs[j]).X - (bugs[i]).X;
	  ydist = (bugs[j]).Y - (bugs[i]).Y;
	  if ((xdist*xdist+ydist*ydist) < 21) {
            if (((xdist*xmot)<=0) && ((ydist*ymot)<=0))
	      continue;
	    turn(&bugs[i]);
	    break;
          }
        }
        if (!(rand()%15))
          turn(&bugs[i]);
      }
    }
  }

  /*  4.  Clean up and exit:  */

  endwin();

  return EXIT_SUCCESS;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -