/* @@@ @@@ @@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@ @@@ @@@ @@@@@@@@@@@@ @@@@@@@@@@@@ @@@@@@@@@@@@@ @@@ @@@ @@@@ @@@@ @@@@ @@@@ @@@ @@@@ @@@ @@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@@ @@@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@@@@@@@@@@ @@@@ @@@@ @@@ @@@ @@@ @@@ @@@@ @@@@ @@@@@@@@@@@@ @@@ @@@ @@@ @@@ @@ @@ @@@@@@@@@@ @@@ @@@ @@@ @@@ Eric P. Scott Caltech High Energy Physics October, 1980 */ #ifdef SLANG #include "slcurses.h" #else #include #define MALLOC malloc #endif #include #include #ifndef NO_STDLIB_H #include #endif unsigned char *safe_malloc (unsigned int size) { unsigned char *p; p = MALLOC (size); if (p == NULL) { fprintf(stderr, "Malloc error."); exit (-1); } return p; } #define cursor(col,row) move(row,col) int Wrap; short *ref[128]; static char flavor[]={ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; static short xinc[]={ 1, 1, 1, 0, -1, -1, -1, 0 }, yinc[]={ -1, 0, 1, 1, 1, 0, -1, -1 }; static struct worm { int orientation, head; short *xpos, *ypos; } worm[40]; static char *field; static int length=16, number=3, trail=' '; static struct options { int nopts; int opts[3]; } normal[8]={ { 3, { 7, 0, 1 } }, { 3, { 0, 1, 2 } }, { 3, { 1, 2, 3 } }, { 3, { 2, 3, 4 } }, { 3, { 3, 4, 5 } }, { 3, { 4, 5, 6 } }, { 3, { 5, 6, 7 } }, { 3, { 6, 7, 0 } } }, upper[8]={ { 1, { 1, 0, 0 } }, { 2, { 1, 2, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 2, { 4, 5, 0 } }, { 1, { 5, 0, 0 } }, { 2, { 1, 5, 0 } } }, left[8]={ { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 2, { 2, 3, 0 } }, { 1, { 3, 0, 0 } }, { 2, { 3, 7, 0 } }, { 1, { 7, 0, 0 } }, { 2, { 7, 0, 0 } } }, right[8]={ { 1, { 7, 0, 0 } }, { 2, { 3, 7, 0 } }, { 1, { 3, 0, 0 } }, { 2, { 3, 4, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 2, { 6, 7, 0 } } }, lower[8]={ { 0, { 0, 0, 0 } }, { 2, { 0, 1, 0 } }, { 1, { 1, 0, 0 } }, { 2, { 1, 5, 0 } }, { 1, { 5, 0, 0 } }, { 2, { 5, 6, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } } }, upleft[8]={ { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 1, { 3, 0, 0 } }, { 2, { 1, 3, 0 } }, { 1, { 1, 0, 0 } } }, upright[8]={ { 2, { 3, 5, 0 } }, { 1, { 3, 0, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 1, { 5, 0, 0 } } }, lowleft[8]={ { 3, { 7, 0, 1 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 1, { 1, 0, 0 } }, { 2, { 1, 7, 0 } }, { 1, { 7, 0, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } } }, lowright[8]={ { 0, { 0, 0, 0 } }, { 1, { 7, 0, 0 } }, { 2, { 5, 7, 0 } }, { 1, { 5, 0, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } }, { 0, { 0, 0, 0 } } }; static void onsig (int); static float ranf (void); int main(int argc, char *argv[]) { int x, y; int n; struct worm *w; struct options *op; int h; short *ip; int last, bottom; int counts = -1; for (x=1;x1024) { fprintf(stderr,"%s: Invalid length\n",*argv); exit(1); } break; case 'n': if (++x==argc) goto usage; if ((number=atoi(argv[x]))<1||number>40) { fprintf(stderr,"%s: Invalid number of worms\n",*argv); exit(1); } break; case 't': trail='.'; break; default: usage: fprintf(stderr, "usage: %s [-field] [-length #] [-number #] [-trail]\n",*argv); exit(1); break; } } #ifdef SLANG SLang_init_tty (7, 0, 0); SLtt_init_video (); #endif #ifdef SIGINT signal(SIGINT, onsig); #endif #ifdef SLANG SLtt_Use_Ansi_Colors = 1; #endif initscr(); bottom = LINES-1; last = COLS-1; ip=(short *)safe_malloc(LINES*COLS*sizeof (short)); for (n=0;n=0;) *ip++=0; ref[bottom][last]=0; for (n=number, w= &worm[0];--n>=0;w++) { w->orientation=w->head=0; if (!(ip=(short *)safe_malloc(length*sizeof (short)))) { fprintf(stderr,"%s: out of memory\n",*argv); exit(1); } w->xpos=ip; for (x=length;--x>=0;) *ip++ = -1; if (!(ip=(short *)safe_malloc(length*sizeof (short)))) { fprintf(stderr,"%s: out of memory\n",*argv); exit(1); } w->ypos=ip; for (y=length;--y>=0;) *ip++ = -1; } if (field) { register char *p; p=field; for (y=bottom;--y>=0;) { for (x=COLS;--x>=0;) { addch(*p++); if (!*p) p=field; } move(y, 0); } } refresh(); while (counts--) { for (n=0, w = &worm[0]; n < number;n++,w++) { #ifdef SLANG SLsmg_set_color (n % 16); #endif /* Worm starts at bottom left */ if ((x=w->xpos[h=w->head])<0) { cursor(x=w->xpos[h]=0,y=w->ypos[h]=bottom); addch(flavor[n%16]); ref[y][x]++; } else y=w->ypos[h]; if (++h==length) h=0; if (w->xpos[w->head=h]>=0) { /* No need to worry about ypos since it is greater than * zero from above */ register int x1, y1; x1=w->xpos[h]; y1=w->ypos[h]; if (--ref[y1][x1]==0) { cursor(x1,y1); #ifdef SLANG SLsmg_set_color (0); #endif addch(trail); #ifdef SLANG SLsmg_set_color (n % 16); #endif } } op= &(x==0 ? (y==0 ? upleft : (y==bottom ? lowleft : left)) : (x==last ? (y==0 ? upright : (y==bottom ? lowright : right)) : (y==0 ? upper : (y==bottom ? lower : normal))))[w->orientation]; switch (op->nopts) { case 0: refresh(); endwin(); abort(); return -1; case 1: w->orientation=op->opts[0]; break; default: w->orientation=op->opts[(int)(ranf()*(float)op->nopts)]; } cursor(x += xinc[w->orientation], y += yinc[w->orientation]); if (!Wrap || x!=last || y!=bottom) { addch(flavor[n%16]); } ref[w->ypos[h]=y][w->xpos[h]=x]++; } refresh(); #ifdef SLANG if (SLang_input_pending (1)) break; #endif } refresh (); onsig (0); return 0; } static void onsig (int sig) { endwin(); #ifdef SLANG SLtt_reset_video (); SLtt_del_eol (); SLang_reset_tty (); #endif exit (sig); } static float ranf(void) { float rv; long r = rand(); r &= 077777; rv =((float)r/32767.); return rv; }