[net.sources.games] A modified worms program

josh@hi.UUCP (02/24/87)

Today came in the news a little program that does worms.  It
 was late at I had little else to do so I went in and made
 it terminal independent.

I think some termcap guru could clean up my coding for
 sysinit if they were in the mood.  I never have worked with
 pure termcap so had not figured out it's little problems.

			--Josh Siegel


#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	worms
# This archive created: Tue Feb 24 00:18:33 1987
echo shar: creating directory worms
mkdir worms
cd worms
echo shar: extracting worms.c '(5425 characters)'
sed 's/^XX//' << \SHAR_EOF > worms.c
XX/*
XX * History : Written by tjalk.cs.vu.nl  ( I got no name from the article) 
XX *
XX * Hacked to use termcap by: Josh Siegel (josh@hi.unm@hc.dspo.gov) 
XX *
XX *
XX * Please note, The hack that handles loading the atributes into the system
XX * is exactly that... a hack.  I had little time and little want to make
XX * it better. 
XX *
XX *
XX * --Josh Siegel 
XX *
XX */
XX#define MaxNrOfWorms 32		/* You can't alter this without altering
XX				 * the zoo!  (Zoo: see somewhere else in
XX				 * this program)      */
XX#define MaxLength   256		/* This really is long enough! */
XXint             ScreenWidth;
XXint             ScreenHeigth;
XXchar            cm[16], cl[16];
XX
XX
XX#include <stdio.h>
XX
XX
XXint             wormlength = 20;/* 20 by default, can be redefined by
XX				 * -l<nr> */
XXint             nrofworms = 3;	/* 3 by default, can be redefined by
XX				 * -n<nr> */
XXchar           *message = "				W O R M S ! ! !";
XX/* message can be redifined by -m<string> */
XX
XXint             x_direction[8] = {1, 1, 0, -1, -1, -1, 0, 1};
XXint             y_direction[8] = {0, 1, 1, 1, 0, -1, -1, -1};
XX
XXint             screen[100][100];
XX
XX
XX
XXmain(argc, argv)
XX  char          **argv;
XX
XX{
XX  int             wormx[MaxNrOfWorms][MaxLength], wormy[MaxNrOfWorms][MaxLength];
XX  int             dir[MaxNrOfWorms], i, j;
XX  int             ptr1, ptr2, x, y, *direction;
XX  long            dummy;
XX  char           *pos();
XX
XX
XX  /* First test for any flags... */
XX
XX  for (i = 1; i < argc; i++)
XX    if (argv[i][0] == '-') {
XX      switch (argv[i][1]) {
XX      case 'l':
XX	if (
XX	    sscanf(argv[i], "-l%d", &wormlength) == 0 ||
XX	    wormlength < 2 || wormlength > MaxLength) {
XX	  puts("Bad length.");
XX	  exit(1);
XX	} break;
XX      case 'n':
XX	if (
XX	    sscanf(argv[i], "-n%d", &nrofworms) == 0 ||
XX	    nrofworms < 1 || nrofworms > MaxNrOfWorms) {
XX	  puts("Bad number of worms.");
XX	  exit(1);
XX	} break;
XX      case 'm':
XX	message = argv[i] + 2;
XX	break;
XX      default:
XX	printf(" -%c: bad option.\n", argv[i][1]);
XX	exit(1);
XX      }
XX    } else {
XX      printf("Syntax: %s [ -l<nr> ] [ -n<nr> ] \
XX[ -m<message> ]\n", argv[0]);
XX      exit(1);
XX    }
XX
XX  /* Now let's initialize !! */
XX
XX  initsys();
XX  clear_screen();
XX  printf("%s%s", pos(0, 22), message);
XX
XX  for (j = 0; j < nrofworms; j++) {
XX    for (i = 0; i < wormlength; i++)
XX      wormx[j][i] = wormy[j][i] = 0;
XX    dir[j] = 1;			/* direction of worm j */
XX  }
XX
XX  screen[0][0] = nrofworms * wormlength;
XX  ptr1 = ptr2 = 0;
XX  /* They point to the front and the back of a worm, respectively. */
XX
XX
XX  /* init randomizer... I hope this will work, it works on UNIX */
XX  srand((int) time(&dummy));
XX
XX
XX
XX
XX  while (1) {
XX    ptr2 = (ptr1 + 1) % wormlength;
XX    /* Take the next part of each worm. */
XX
XX    for (i = 0; i < nrofworms; i++) {
XX      int             enough = 0;
XX
XX      x = wormx[i][ptr2];
XX      y = wormy[i][ptr2];
XX      /*
XX       * x and y are the coordinates of the tail of worm i, /* which has
XX       * to be removed.			 
XX       */
XX      if ((--screen[x][y]) == 0)
XX	printf("%s ", pos(x, y));
XX      /*
XX       * It will only be removed when there are no other /* "parts" of
XX       * worms on that spot on the screen.  
XX       */
XX
XX      /* Now put a head somewhere. */
XX      /*
XX       * We'll modify the direction just until we've got a correct
XX       * direction (so that the worm will not cross or  overlap another
XX       * worm or itself, nor will run of the screen),  or that we've had
XX       * enough,  since than there probably is no such direction. 
XX       */
XX
XX      direction = &dir[i];
XX
XX      do
XX	*direction = (*direction + (rand()) % 3 + 7) % 8;
XX      while ((x = wormx[i][ptr1] + x_direction[*direction]) < 0 ||
XX	     x > ScreenWidth - 1 ||
XX	     (y = wormy[i][ptr1] + y_direction[*direction]) < 0 ||
XX	     y > ScreenHeigth - 2 ||
XX	     ((screen[x][y] != 0 || cross(x, y, *direction))
XX	      && enough++ < 19));
XX
XX      if (enough >= 19) {	/* We can't move this poor worm */
XX	x = wormx[i][ptr1];	/* old coordinates  */
XX	y = wormy[i][ptr1];
XX      }
XX      /*
XX       * x and y now contain the new coordinates of the worms head. Let's
XX       * just place it on the screen (and in memory) 
XX       */
XX      wormx[i][ptr2] = x;
XX      wormy[i][ptr2] = y;
XX      printf("%s%c", pos(x, y),
XX	     "*#Ox@~.+!&%$'`=-oXwW()^~*#x0@+./"[i]);
XX      /* Welcome to the zoo!! ^^^^ */
XX      screen[x][y]++;
XX    }
XX    ptr1 = ptr2;
XX  }
XX}
XX
XX
XX
XX
XXcross(x, y, d)
XX{				/* keeps two worms from crossing */
XX
XX
XX
XX
XX
XX  if (d & 1 == 0)
XX    return 0;			/* worm moving diogonally? */
XX
XX  return (screen[x][y - y_direction[d]] && screen[x - x_direction[d]][y]);
XX}
XX
XX/*
XX * I assume there are betters ways of doing this but since I had no
XX * interest in spending more then 5 minutes making this use termcap ... 
XX */
XX
XXinitsys()
XX{
XX  static char     hasrun = 0, bp[1024], bp2[1024], *tgetstr(), *p1;
XX  char           *tmp;
XX
XX  tgetent(bp, getenv("TERM"));
XX  strcpy(bp2, bp);
XX  p1 = bp2;
XX  tmp = tgetstr("cl", &p1);
XX  strcpy(cl, tmp);
XX  strcpy(bp2, bp);
XX  p1 = bp2;
XX  tmp = tgetstr("cm", &p1);
XX  strcpy(cm, tmp);
XX  strcpy(bp2, bp);
XX  p1 = bp2;
XX  if ((ScreenHeigth = tgetnum("li", &p1) - 1) > 99) {
XX    printf("I cannot handle a terminal that has more then 99 lines\n");
XX    exit(0);
XX  }
XX  strcpy(bp2, bp);
XX  p1 = bp2;
XX  if ((ScreenWidth = tgetnum("co", &p1) - 1) > 99) {;
XX    printf("I cannot handle a terminal that has more then 99 rows\n");
XX    exit(0);
XX  }
XX}
XX
XXchar           *
XXpos(x, y)
XX{
XX  char           *ret, *tgoto();
XX
XX  ret = tgoto(cm, x, y);
XX  return ret;
XX}
XX
XX
XX
XXclear_screen()
XX{
XX  puts(cl);
XX}
SHAR_EOF
if test 5425 -ne "`wc -c worms.c`"
then
echo shar: error transmitting worms.c '(should have been 5425 characters)'
fi
echo shar: extracting Makefile '(60 characters)'
sed 's/^XX//' << \SHAR_EOF > Makefile
XXCFLAGS= -O
XX
XXworms:worms.o
XX	${CC} ${CFLAGS} -o worms worms.o
SHAR_EOF
if test 60 -ne "`wc -c Makefile`"
then
echo shar: error transmitting Makefile '(should have been 60 characters)'
fi
echo shar: done with directory worms
cd ..
#	End of shell archive
exit 0