snake.c -- a slightly enhanced version of the "worm" game
Mitch Lukaart
mitch at gitpyr.UUCP
Mon Jan 7 09:48:51 AEST 1985
> Happy New Year to Everyone! I was taking a leisure time break when I
> suddenly realized a small enhancement could be made to "worm".
> Snake has a cute little serpentine head that points in the direction
> you're going, after the snake wakes up and starts stalking his food.
> Apart from flushing buffers at the end so you won't lose your score,
> this is the only real change. The whole source is here in case you
> didn't already have it. Don't forget to remove the .signature at the end.
>
> So long, and thanks for all the fish.
> Dave Fiedler
>
> -------------------- cut here -----------------------
> /*
> * Snake, from worm Written by Michael Toy
> * UCSC
> * modified by a.wiedemann 05.17.82
> * Siemens AG Munich
> * ZTI INF 212
> *
> * herpetology added by David Fiedler, InfoPro Systems
> * {astrovax, harpo, whuxcc}!infopro!dave
> *
> * compile with "cc -O -s -o snake snake.c -lcurses -ltermcap
> *
> */
>
> #include <ctype.h>
> #include "curses.h"
> #include <signal.h>
>
> char *getenv();
>
> #define newlink() (struct body *) malloc(sizeof (struct body));
> #define HEAD '@'
> #define BODY 'o'
> #define UP 1
> #define DOWN 2
> #define LEFT 3
> #define RIGHT 4
> #define LENGTH 7
> #define RUNLEN 8
> #define when break;case
> #define otherwise break;default
> #define CNTRL(p) ('p'-'A'+1)
>
> WINDOW *tv;
> WINDOW *stw;
> struct body {
> int x;
> int y;
> struct body *prev;
> struct body *next;
> } *head, *tail, goody, *malloc();
>
> int growing = 0;
> int running = 0;
> int score = 0;
> int start_len = LENGTH;
> char lastch;
> char outbuf[BUFSIZ];
>
> main(argc, argv)
> char **argv;
> {
> int leave(), wake(), suspend();
> char ch;
>
> if (argc == 2)
> {
> start_len = atoi(argv[1]);
> score += (start_len - LENGTH);
> }
> setbuf(stdout, outbuf);
> srand(getpid());
> signal(SIGALRM, wake);
> signal(SIGINT, leave);
> signal(SIGQUIT, leave);
> #ifdef SIGTSTP
> signal(SIGTSTP, suspend); /* process control signal */
> #endif
> initscr();
> crmode();
> noecho();
> clear();
> stw = newwin(1, COLS-1, 0, 0);
> tv = newwin(LINES-1, COLS-1, 1, 0);
> /* snake cannot be bigger than the inner width of tv window !! */
> if ((start_len <= 0) || (start_len > COLS - 6))
> start_len = LENGTH;
> box(tv, '*', '*');
> scrollok(tv, FALSE);
> scrollok(stw, FALSE);
> wmove(stw, 0, 0);
> wprintw(stw, " Snake");
> refresh();
> wrefresh(stw);
> wrefresh(tv);
> life(); /* Create the snake */
> prize(); /* Put up a goal */
> for (;;)
> {
> if (running)
> {
> running--;
> process(lastch);
> }
> else
> {
> fflush(stdout);
> if (read(0, &ch, 1) >= 0)
> process(ch);
> }
> }
> }
>
> life()
> {
> register struct body *bp, *np;
> register int i;
>
> head = newlink();
> head->x = start_len+2;
> head->y = 12;
> head->next = NULL;
> display(head, HEAD);
> for (i = 0, bp = head; i < start_len; i++, bp = np) {
> np = newlink();
> np->next = bp;
> bp->prev = np;
> np->x = bp->x - 1;
> np->y = bp->y;
> display(np, BODY);
> }
> tail = np;
> tail->prev = NULL;
> wrefresh(tv);
> }
>
> display(pos, chr)
> struct body *pos;
> char chr;
> {
> wmove(tv, pos->y, pos->x);
> waddch(tv, chr);
> }
>
> leave()
> {
> move(LINES - 1, 0);
> refresh();
> endwin();
> exit(0);
> }
>
> wake()
> {
> signal(SIGALRM, wake);
> fflush(stdout);
> process(lastch);
> }
>
> rnd(range)
> {
> return abs((rand()>>5)+(rand()>>5)) % range;
> }
>
> newpos(bp)
> struct body * bp;
> {
> do {
> bp->y = rnd(LINES-3)+ 2;
> bp->x = rnd(COLS-3) + 1;
> wmove(tv, bp->y, bp->x);
> } while(winch(tv) != ' ');
> }
>
> prize()
> {
> int value;
>
> value = rnd(9) + 1;
> newpos(&goody);
> waddch(tv, value+'0');
> wrefresh(tv);
> }
>
> process(ch)
> char ch;
> {
> register int x,y;
> struct body *nh;
> static char headchar, dir;
>
> alarm(0);
> x = head->x;
> y = head->y;
> switch(ch)
> {
> when 'h': x--; dir=LEFT;
> when 'j': y++; dir=DOWN;
> when 'k': y--; dir=UP;
> when 'l': x++; dir=RIGHT;
> when 'H': x--; running = RUNLEN; ch = tolower(ch);dir=LEFT;
> when 'J': y++; running = RUNLEN/2; ch = tolower(ch);dir=DOWN;
> when 'K': y--; running = RUNLEN/2; ch = tolower(ch);dir=UP;
> when 'L': x++; running = RUNLEN; ch = tolower(ch);dir=RIGHT;
> when '\f': setup(); return;
> when CNTRL(Z): suspend(); return;
> when CNTRL(C): crash(); return;
> when CNTRL(D): crash(); return;
> otherwise: if (! running) alarm(1);
> return;
> }
> lastch = ch;
> if (growing == 0)
> {
> display(tail, ' ');
> tail->next->prev = NULL;
> nh = tail->next;
> free(tail);
> tail = nh;
> }
> else growing--;
> display(head, BODY);
> wmove(tv, y, x);
> if (isdigit(ch = winch(tv)))
> {
> growing += ch-'0';
> prize();
> score += growing;
> running = 0;
> wmove(stw, 0, 68);
> wprintw(stw, "Score: %3d", score);
> wrefresh(stw);
> }
> else if(ch != ' ') crash();
> nh = newlink();
> nh->next = NULL;
> nh->prev = head;
> head->next = nh;
> nh->y = y;
> nh->x = x;
> switch (dir) {
> case UP:
> headchar = '^'; break;
> case DOWN:
> headchar = 'V'; break;
> case LEFT:
> headchar = '<' ; break;
> case RIGHT:
> headchar = '>' ; break;
> default:
> headchar = HEAD ;
> }
> display(nh, headchar);
> head = nh;
> wrefresh(tv);
> if (! running) alarm(1);
> }
>
> crash()
> {
> sleep(1);
> clear();
> move(LINES - 1, 0);
> refresh();
> endwin();
> fflush(stdout);
> printf("Well you ran into something and the game is over.\n");
> printf("Your final score was %d\n", score);
> leave();
> }
>
> suspend()
> {
> char *sh;
>
> move(LINES-1, 0);
> refresh();
> endwin();
> fflush(stdout);
> #ifdef SIGTSTP
> kill(getpid(), SIGTSTP);
> signal(SIGTSTP, suspend);
> #else
> sh = getenv("SHELL");
> if (sh == NULL)
> sh = "/bin/sh";
> system(sh);
> #endif
> crmode();
> noecho();
> setup();
> }
>
> setup()
> {
> clear();
> refresh();
> touchwin(stw);
> wrefresh(stw);
> touchwin(tv);
> wrefresh(tv);
> alarm(1);
> }
> --
> Dave Fiedler
> {harpo,astrovax,whuxcc,clyde}!infopro!dave
> USMail: InfoPro Systems, 3108 Route 10, Denville, NJ 07834
> People Phone: (201) 989-0570
*** REPLACE THIS LINE WITH YOUR MESSAGE ***
More information about the Comp.sources.unix
mailing list