home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource5
/
332_01
/
bugs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-30
|
11KB
|
517 lines
/*----------------------------------------------------*- 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