/* * History : Written by tjalk.cs.vu.nl ( I got no name from the article) * * Hacked to use termcap by: Josh Siegel (josh@hi.unm@hc.dspo.gov) * * * Please note, The hack that handles loading the atributes into the system * is exactly that... a hack. I had little time and little want to make * it better. * * * --Josh Siegel * * Re-hacked by: Tom Hageman. */ char Zoo[] = "*#Ox@~.+!&%$'`=-oXwW()^~*#x0@+./"; /* welcome to the Zoo */ #define MaxNrOfWorms (sizeof Zoo - 1) #define MaxLength 64 /* This really is long enough! */ int ScreenWidth; int ScreenHeigth; char *cm, *cl, *vi, *ve; #include #include char *strcpy(); void end(); int wormlength = 20;/* 20 by default, can be redefined by * -l */ int nrofworms = 3; /* 3 by default, can be redefined by * -n */ char *message = " W O R M S ! ! !"; /* message can be redifined by -m */ int x_direction[8] = {1, 1, 0, -1, -1, -1, 0, 1}; int y_direction[8] = {0, 1, 1, 1, 0, -1, -1, -1}; int screen[100][100]; main(argc, argv) char **argv; { int wormx[MaxNrOfWorms][MaxLength], wormy[MaxNrOfWorms][MaxLength]; int dir[MaxNrOfWorms], i, j; int ptr1, ptr2, x, y, *direction; long dummy; char *pos(); setbuf(stdout, NULL); /* First test for any flags... */ for (i = 1; i < argc; i++) if (argv[i][0] == '-') { switch (argv[i][1]) { case 'l': case 'L': if ( sscanf(argv[i], "-l%d", &wormlength) == 0 || wormlength < 2 || wormlength > MaxLength) { puts("Bad length."); exit(1); } break; case 'n': case 'N': if ( sscanf(argv[i], "-n%d", &nrofworms) == 0 || nrofworms < 1 || nrofworms > MaxNrOfWorms) { puts("Bad number of worms."); exit(1); } break; case 'm': case 'M': message = argv[i] + 2; break; default: printf(" -%c: bad option.\n", argv[i][1]); exit(1); } } else { printf("Syntax: %s [ -l ] [ -n ] \ [ -m ]\n", argv[0]); exit(1); } /* Now let's initialize !! */ initsys(); if (vi) puts(vi); signal(SIGINT, end); clear_screen(); printf("%s%s", pos(0, 22), message); for (j = 0; j < nrofworms; j++) { for (i = 0; i < wormlength; i++) wormx[j][i] = wormy[j][i] = 0; dir[j] = 1; /* direction of worm j */ } screen[0][0] = nrofworms * wormlength; ptr1 = ptr2 = 0; /* They point to the front and the back of a worm, respectively. */ /* init randomizer... I hope this will work, it works on UNIX */ srand((int) time(&dummy)); while (1) { ptr2 = (ptr1 + 1) % wormlength; /* Take the next part of each worm. */ for (i = 0; i < nrofworms; i++) { int enough = 0; x = wormx[i][ptr2]; y = wormy[i][ptr2]; /* * x and y are the coordinates of the tail of worm i, which has * to be removed. */ if ((--screen[x][y]) == 0) printf("%s ", pos(x,y)); /* * It will only be removed when there are no other "parts" of * worms on that spot on the screen. */ /* Now put a head somewhere. */ /* * We'll modify the direction just until we've got a correct * direction (so that the worm will not cross or overlap another * worm or itself, nor will run of the screen), or that we've had * enough, since than there probably is no such direction. */ direction = &dir[i]; do *direction = (*direction + (rand()) % 3 + 7) % 8; while ((x = wormx[i][ptr1] + x_direction[*direction]) < 0 || x > ScreenWidth - 1 || (y = wormy[i][ptr1] + y_direction[*direction]) < 0 || y > ScreenHeigth - 2 || ((screen[x][y] != 0 || cross(x, y, *direction)) && enough++ < 19)); if (enough >= 19) { /* We can't move this poor worm */ x = wormx[i][ptr1]; /* old coordinates */ y = wormy[i][ptr1]; } /* * x and y now contain the new coordinates of the worms head. Let's * just place it on the screen (and in memory) */ wormx[i][ptr2] = x; wormy[i][ptr2] = y; printf("%s%c", pos(x, y), Zoo[i]); screen[x][y]++; } ptr1 = ptr2; } } cross(x, y, d) { /* keeps two worms from crossing */ if (d & 1 == 0) return 0; /* worm moving diagonally? */ return (screen[x][y - y_direction[d]] && screen[x - x_direction[d]][y]); } /* * I assume there are betters ways of doing this but since I had no * interest in spending more then 5 minutes making this use termcap ... */ initsys() { static char strs[100]; char bp[2048]; char *p1 = strs, *getenv(), *tgetstr(); if (tgetent(bp, getenv("TERM")) <= 0) { printf("tgetent failed for terminal \"%s\"\n", getenv("TERM")); exit(1); } cl = tgetstr("cl", &p1); cm = tgetstr("cm", &p1); vi = tgetstr("vi", &p1); ve = tgetstr("ve", &p1); if ((ScreenHeigth = tgetnum("li") - 1) > 99) { ScreenHeigth = 99; } if ((ScreenWidth = tgetnum("co") - 1) > 99) {; ScreenWidth = 99; } if (!cm || ScreenWidth < 0 || ScreenHeigth < 0) { printf("Terminal \"%s\" is too dumb to run worms.\n", getenv("TERM")); exit(1); } } static char *out_p; static outc(c) { if (c) *out_p++ = c; } short ospeed; /* for tputs */ char PC; char * pos(x, y) { static char result[40]; char *ret, *tgoto(); out_p = result; tputs(tgoto(cm, x, y), 1, outc); *out_p = '\0'; return result; } clear_screen() { if (cl) puts(cl); } /* catch signal */ void end(sig) { if (ve) puts(ve); clear_screen(); exit(0); }