home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / program / termcap / worms.c < prev   
C/C++ Source or Header  |  1987-10-26  |  6KB  |  233 lines

  1. /*
  2.  * History : Written by tjalk.cs.vu.nl  ( I got no name from the article) 
  3.  *
  4.  * Hacked to use termcap by: Josh Siegel (josh@hi.unm@hc.dspo.gov) 
  5.  *
  6.  *
  7.  * Please note, The hack that handles loading the atributes into the system
  8.  * is exactly that... a hack.  I had little time and little want to make
  9.  * it better. 
  10.  *
  11.  *
  12.  * --Josh Siegel 
  13.  *
  14.  */
  15. #define MaxNrOfWorms 32        /* You can't alter this without altering
  16.                  * the zoo!  (Zoo: see somewhere else in
  17.                  * this program)      */
  18. #define MaxLength   64        /* This really is long enough! */
  19. int             ScreenWidth;
  20. int             ScreenHeigth;
  21. char            cm[16], cl[16];
  22.  
  23.  
  24. #include <stdio.h>
  25. char        *strcpy();
  26.  
  27. int             wormlength = 20;/* 20 by default, can be redefined by
  28.                  * -l<nr> */
  29. int             nrofworms = 3;    /* 3 by default, can be redefined by
  30.                  * -n<nr> */
  31. char           *message = "                W O R M S ! ! !";
  32. /* message can be redifined by -m<string> */
  33.  
  34. int             x_direction[8] = {1, 1, 0, -1, -1, -1, 0, 1};
  35. int             y_direction[8] = {0, 1, 1, 1, 0, -1, -1, -1};
  36.  
  37. int             screen[100][100];
  38.  
  39.  
  40.  
  41. main(argc, argv)
  42.   char          **argv;
  43.  
  44. {
  45.   int             wormx[MaxNrOfWorms][MaxLength], wormy[MaxNrOfWorms][MaxLength];
  46.   int             dir[MaxNrOfWorms], i, j;
  47.   int             ptr1, ptr2, x, y, *direction;
  48.   long            dummy;
  49.   char           *pos();
  50.  
  51.  
  52.   setbuf(stdout, NULL);
  53.   /* First test for any flags... */
  54.  
  55.   for (i = 1; i < argc; i++)
  56.     if (argv[i][0] == '-') {
  57.       switch (argv[i][1]) {
  58.       case 'l':
  59.       case 'L':
  60.     if (
  61.         sscanf(argv[i], "-l%d", &wormlength) == 0 ||
  62.         wormlength < 2 || wormlength > MaxLength) {
  63.       puts("Bad length.");
  64.       exit(1);
  65.     } break;
  66.       case 'n':
  67.       case 'N':
  68.     if (
  69.         sscanf(argv[i], "-n%d", &nrofworms) == 0 ||
  70.         nrofworms < 1 || nrofworms > MaxNrOfWorms) {
  71.       puts("Bad number of worms.");
  72.       exit(1);
  73.     } break;
  74.       case 'm':
  75.       case 'M':
  76.     message = argv[i] + 2;
  77.     break;
  78.       default:
  79.     printf(" -%c: bad option.\n", argv[i][1]);
  80.     exit(1);
  81.       }
  82.     } else {
  83.       printf("Syntax: %s [ -l<nr> ] [ -n<nr> ] \
  84. [ -m<message> ]\n", argv[0]);
  85.       exit(1);
  86.     }
  87.  
  88.   /* Now let's initialize !! */
  89.  
  90.   initsys();
  91.   clear_screen();
  92.   printf("%s%s", pos(0, 22), message);
  93.  
  94.   for (j = 0; j < nrofworms; j++) {
  95.     for (i = 0; i < wormlength; i++)
  96.       wormx[j][i] = wormy[j][i] = 0;
  97.     dir[j] = 1;            /* direction of worm j */
  98.   }
  99.  
  100.   screen[0][0] = nrofworms * wormlength;
  101.   ptr1 = ptr2 = 0;
  102.   /* They point to the front and the back of a worm, respectively. */
  103.  
  104.  
  105.   /* init randomizer... I hope this will work, it works on UNIX */
  106.   srand((int) time(&dummy));
  107.  
  108.  
  109.  
  110.  
  111.   while (1) {
  112.     ptr2 = (ptr1 + 1) % wormlength;
  113.     /* Take the next part of each worm. */
  114.  
  115.     for (i = 0; i < nrofworms; i++) {
  116.       int             enough = 0;
  117.  
  118.       x = wormx[i][ptr2];
  119.       y = wormy[i][ptr2];
  120.       /*
  121.        * x and y are the coordinates of the tail of worm i, which has
  122.        * to be removed.             
  123.        */
  124.       if ((--screen[x][y]) == 0)
  125.     printf("%s ", pos(x, y));
  126.       /*
  127.        * It will only be removed when there are no other "parts" of
  128.        * worms on that spot on the screen.  
  129.        */
  130.  
  131.       /* Now put a head somewhere. */
  132.       /*
  133.        * We'll modify the direction just until we've got a correct
  134.        * direction (so that the worm will not cross or  overlap another
  135.        * worm or itself, nor will run of the screen),  or that we've had
  136.        * enough,  since than there probably is no such direction. 
  137.        */
  138.  
  139.       direction = &dir[i];
  140.  
  141.       do
  142.     *direction = (*direction + (rand()) % 3 + 7) % 8;
  143.       while ((x = wormx[i][ptr1] + x_direction[*direction]) < 0 ||
  144.          x > ScreenWidth - 1 ||
  145.          (y = wormy[i][ptr1] + y_direction[*direction]) < 0 ||
  146.          y > ScreenHeigth - 2 ||
  147.          ((screen[x][y] != 0 || cross(x, y, *direction))
  148.           && enough++ < 19));
  149.  
  150.       if (enough >= 19) {    /* We can't move this poor worm */
  151.     x = wormx[i][ptr1];    /* old coordinates  */
  152.     y = wormy[i][ptr1];
  153.       }
  154.       /*
  155.        * x and y now contain the new coordinates of the worms head. Let's
  156.        * just place it on the screen (and in memory) 
  157.        */
  158.       wormx[i][ptr2] = x;
  159.       wormy[i][ptr2] = y;
  160.       printf("%s%c", pos(x, y),
  161.          "*#Ox@~.+!&%$'`=-oXwW()^~*#x0@+./"[i]);
  162.       /* Welcome to the zoo!! ^^^^ */
  163.       screen[x][y]++;
  164.     }
  165.     ptr1 = ptr2;
  166.   }
  167. }
  168.  
  169.  
  170.  
  171.  
  172. cross(x, y, d)
  173. {                /* keeps two worms from crossing */
  174.  
  175.  
  176.  
  177.  
  178.  
  179.   if (d & 1 == 0)
  180.     return 0;            /* worm moving diagonally? */
  181.  
  182.   return (screen[x][y - y_direction[d]] && screen[x - x_direction[d]][y]);
  183. }
  184.  
  185. /*
  186.  * I assume there are betters ways of doing this but since I had no
  187.  * interest in spending more then 5 minutes making this use termcap ... 
  188.  */
  189.  
  190. initsys()
  191. {
  192.   static char     hasrun = 0, bp[1024], bp2[1024], *tgetstr(), *p1;
  193.   char           *tmp, *getenv();
  194.  
  195.   tgetent(bp, getenv("TERM"));
  196.   strcpy(bp2, bp);
  197.   p1 = bp2;
  198.   tmp = tgetstr("cl", &p1);
  199.   strcpy(cl, tmp);
  200.   strcpy(bp2, bp);
  201.   p1 = bp2;
  202.   tmp = tgetstr("cm", &p1);
  203.   strcpy(cm, tmp);
  204.   strcpy(bp2, bp);
  205.   p1 = bp2;
  206.   if ((ScreenHeigth = tgetnum("li", &p1) - 1) > 99) {
  207.     printf("I cannot handle a terminal that has more then 99 lines\n");
  208.     exit(0);
  209.   }
  210.   strcpy(bp2, bp);
  211.   p1 = bp2;
  212.   if ((ScreenWidth = tgetnum("co", &p1) - 1) > 99) {;
  213.     printf("I cannot handle a terminal that has more then 99 rows\n");
  214.     exit(0);
  215.   }
  216. }
  217.  
  218. char           *
  219. pos(x, y)
  220. {
  221.   char           *ret, *tgoto();
  222.  
  223.   ret = tgoto(cm, x, y);
  224.   return ret;
  225. }
  226.  
  227.  
  228.  
  229. clear_screen()
  230. {
  231.   puts(cl);
  232. }
  233.