wutka@gitpyr.UUCP (Mark Wutka) (09/17/85)
Due to numerous requests for both sources of snake, here they are. There are two files - snake.c (which is the original which was posted to the net around this time last year, I think) and snake2.c which has my modifications. This is a shar archive file. Mark Wutka Georgia Institute of Technology ------------------------cut here------------------------ #! /bin/sh # Run the following text with /bin/sh to create: # snake.c # snake2.c if test -f 'snake.c' then echo "`basename $0`: can't extract" 'snake.c' "- file exists" 1>&2 else sed 's/^X//' << '--End_of_snake.c--' > 'snake.c' X/* X * Snake, from worm Written by Michael Toy X * UCSC X * modified by a.wiedemann 05.17.82 X * Siemens AG Munich X * ZTI INF 212 X * X * herpetology added by David Fiedler, InfoPro Systems X * {astrovax, harpo, whuxcc}!infopro!dave X * X * compile with "cc -O -s -o snake snake.c -lcurses -ltermcap X * X */ X X#include <ctype.h> X#include "curses.h" X#include <signal.h> X Xchar *getenv(); X X#define newlink() (struct body *) malloc(sizeof (struct body)); X#define HEAD '@' X#define BODY 'o' X#define UP 1 X#define DOWN 2 X#define LEFT 3 X#define RIGHT 4 X#define LENGTH 7 X#define RUNLEN 8 X#define when break;case X#define otherwise break;default X#define CNTRL(p) ('p'-'A'+1) X XWINDOW *tv; XWINDOW *stw; Xstruct body { X int x; X int y; X struct body *prev; X struct body *next; X} *head, *tail, goody, *malloc(); X Xint growing = 0; Xint running = 0; Xint score = 0; Xint start_len = LENGTH; Xint pd=RIGHT; Xchar twist; Xchar lastch; Xchar outbuf[BUFSIZ]; X Xmain(argc, argv) Xchar **argv; X{ X int leave(), wake(), suspend(); X char ch; X X if (argc == 2) X { X start_len = atoi(argv[1]); X score += (start_len - LENGTH); X } X setbuf(stdout, outbuf); X srand(getpid()); X signal(SIGALRM, wake); X signal(SIGINT, leave); X signal(SIGQUIT, leave); X#ifdef SIGTSTP X signal(SIGTSTP, suspend); /* process control signal */ X#endif X initscr(); X crmode(); X noecho(); X clear(); X stw = newwin(1, COLS-1, 0, 0); X tv = newwin(LINES-1, COLS-1, 1, 0); X /* snake cannot be bigger than the inner width of tv window !! */ X if ((start_len <= 0) || (start_len > COLS - 6)) X start_len = LENGTH; X box(tv, '*', '*'); X scrollok(tv, FALSE); X scrollok(stw, FALSE); X wmove(stw, 0, 0); X wprintw(stw, " Snake"); X refresh(); X wrefresh(stw); X wrefresh(tv); X life(); /* Create the snake */ X prize(); /* Put up a goal */ X for (;;) X { X if (running) X { X running--; X process(lastch); X } X else X { X fflush(stdout); X if (read(0, &ch, 1) >= 0) X process(ch); X } X } X} X Xlife() X{ X register struct body *bp, *np; X register int i; X X head = newlink(); X head->x = start_len+2; X head->y = 12; X head->next = NULL; X display(head, HEAD); X for (i = 0, bp = head; i < start_len; i++, bp = np) { X np = newlink(); X np->next = bp; X bp->prev = np; X np->x = bp->x - 1; X np->y = bp->y; X display(np, '-'); X } X display(np,' '); X display(np->next,' '); X tail = np; X tail->prev = NULL; X wrefresh(tv); X} X Xdisplay(pos, chr) Xstruct body *pos; Xchar chr; X{ X wmove(tv, pos->y, pos->x); X waddch(tv, chr); X} X Xleave() X{ X move(LINES - 1, 0); X refresh(); X endwin(); X exit(0); X} X Xwake() X{ X signal(SIGALRM, wake); X fflush(stdout); X process(lastch); X} X Xrnd(range) X{ X return abs((rand()>>5)+(rand()>>5)) % range; X} X Xnewpos(bp) Xstruct body * bp; X{ X do { X bp->y = rnd(LINES-3)+ 2; X bp->x = rnd(COLS-3) + 1; X wmove(tv, bp->y, bp->x); X } while(winch(tv) != ' '); X} X Xprize() X{ X int value; X X value = rnd(9) + 1; X newpos(&goody); X waddch(tv, value+'0'); X wrefresh(tv); X} X Xprocess(ch) Xchar ch; X{ X register int x,y; X struct body *nh; X static char headchar, dir; X X alarm(0); X x = head->x; X y = head->y; X pd = dir; X switch(ch) X { X when 'h': x--; dir=LEFT; X { X if(pd==LEFT || pd==RIGHT) twist='-'; X if (pd==UP) twist='\\'; X if (pd==DOWN) twist='/';}; X when 'j': y++; dir=DOWN; twist='|'; X { if (pd==UP || pd==DOWN) twist='|'; X if (pd==LEFT) twist='/'; X if (pd==RIGHT) twist='\\';}; X when 'k': y--; dir=UP; twist ='|'; X { if (pd==UP || pd==DOWN) twist='|'; X if (pd==LEFT) twist='\\'; X if (pd==RIGHT) twist='/';}; X when 'l': x++; dir=RIGHT; twist ='-'; X { if (pd==LEFT || pd==RIGHT) twist='-'; X if (pd==UP) twist='/'; X if (pd==DOWN) twist='\\';}; X when 'H': x--; running = RUNLEN; ch = tolower(ch);dir=LEFT; X when 'J': y++; running = RUNLEN/2; ch = tolower(ch);dir=DOWN; X when 'K': y--; running = RUNLEN/2; ch = tolower(ch);dir=UP; X when 'L': x++; running = RUNLEN; ch = tolower(ch);dir=RIGHT; X when '\f': setup(); return; X when CNTRL(Z): suspend(); return; X when CNTRL(C): crash(); return; X when CNTRL(D): crash(); return; X otherwise: if (! running) alarm(1); X return; X } X lastch = ch; X if (growing <= 0) X { X tail->next->prev = NULL; X nh = tail->next; X free(tail); X tail = nh; X if (growing < 0) X growing = 0; X display(tail->next,' '); X } X else growing--; X display(head,twist); X wmove(tv, y, x); X if (isdigit(ch = winch(tv))) X { X growing += ch-'0'; X prize(); X score += growing; X running = 0; X wmove(stw, 0, 68); X wprintw(stw, "Score: %3d", score); X wrefresh(stw); X } X else if(ch != ' ') crash(); X nh = newlink(); X nh->next = NULL; X nh->prev = head; X head->next = nh; X nh->y = y; X nh->x = x; X switch (dir) { X case UP: X headchar = '^'; break; X case DOWN: X headchar = 'V'; break; X case LEFT: X headchar = '<' ; break; X case RIGHT: X headchar = '>' ; break; X default: X headchar = HEAD ; X } X display(nh, headchar); X head = nh; X wrefresh(tv); X if (! running) alarm(1); X} X Xcrash() X{ X sleep(2); X clear(); X move(LINES - 1, 0); X refresh(); X endwin(); X fflush(stdout); X printf("Well you ran into something and the game is over.\n"); X printf("Your final score was %d\n", score); X leave(); X} X Xsuspend() X{ X char *sh; X X move(LINES-1, 0); X refresh(); X endwin(); X fflush(stdout); X#ifdef SIGTSTP X kill(getpid(), SIGTSTP); X signal(SIGTSTP, suspend); X#else X sh = getenv("SHELL"); X if (sh == NULL) X sh = "/bin/sh"; X system(sh); X#endif X crmode(); X noecho(); X setup(); X} X Xsetup() X{ X clear(); X refresh(); X touchwin(stw); X wrefresh(stw); X touchwin(tv); X wrefresh(tv); X alarm(1); X} X --End_of_snake.c-- if test 5868 -ne `wc -c < 'snake.c'` then echo "`basename $0`: error in" 'snake.c' ": sent 5868 chars, received `wc -c < 'snake.c'`" 1>&2 fi fi if test -f 'snake2.c' then echo "`basename $0`: can't extract" 'snake2.c' "- file exists" 1>&2 else sed 's/^X//' << '--End_of_snake2.c--' > 'snake2.c' X/* X * Snake, from worm Written by Michael Toy X * UCSC X * modified by a.wiedemann 05.17.82 X * Siemens AG Munich X * ZTI INF 212 X * X * herpetology added by David Fiedler, InfoPro Systems X * {astrovax, harpo, whuxcc}!infopro!dave X * barriers and double-elongation added by Mark Wutka X * Office of Computing Services X * Georgia Institute of Technology X * X * compile with "cc -O -s -o snake snake.c -lcurses -ltermcap X * X */ X X#include <ctype.h> X#include "curses.h" X#include <signal.h> X Xchar *getenv(); X X#define newlink() (struct body *) malloc(sizeof (struct body)); X#define HEAD '@' X#define BODY 'o' X#define UP 1 X#define DOWN 2 X#define LEFT 3 X#define RIGHT 4 X#define LENGTH 7 X#define RUNLEN 8 X#define when break;case X#define otherwise break;default X#define CNTRL(p) ('p'-'A'+1) X XWINDOW *tv; XWINDOW *stw; Xstruct body { X int x; X int y; X struct body *prev; X struct body *next; X} *head, *tail, goody, *malloc(); X Xint growing = 0; Xint running = 0; Xint score = 0; Xint skill_level =1; Xchar sl; Xint barrier_skill = 0; Xint start_len = LENGTH; Xint pd=RIGHT; Xint dir=RIGHT; Xint grow_rate = 1; Xchar twist; Xchar lastch; Xchar outbuf[BUFSIZ]; X Xmain(argc, argv) Xchar **argv; X{ X int leave(), wake(), suspend(); X char ch; X X if (argc == 2) X { X skill_level=atoi(argv[1]); X } X else X { X printf("Format for running snake:\n"); X printf("snake n\n"); X printf("where n= the skill level (1-4)\n"); X exit(0); X }; X if(skill_level<1) skill_level=1; X if(skill_level>4) skill_level=4; X switch(skill_level) X { X case 1: X start_len=7; X grow_rate=1; X barrier_skill = 1; X break; X case 2: X start_len=10; X grow_rate=1; X barrier_skill = 2; X break; X case 3: X start_len=10; X grow_rate=2; X barrier_skill=3; X break; X case 4: X start_len=15; X grow_rate=2; X barrier_skill=4; X break; X }; X setbuf(stdout, outbuf); X srand(getpid()); X signal(SIGALRM, wake); X signal(SIGINT, leave); X signal(SIGQUIT, leave); X#ifdef SIGTSTP X signal(SIGTSTP, suspend); /* process control signal */ X#endif X initscr(); X crmode(); X noecho(); X clear(); X stw = newwin(1, COLS-1, 0, 0); X tv = newwin(LINES-1, COLS-1, 1, 0); X /* snake cannot be bigger than the inner width of tv window !! */ X if ((start_len <= 0) || (start_len > COLS - 6)) X start_len = LENGTH; X box(tv, '*', '*'); X scrollok(tv, FALSE); X scrollok(stw, FALSE); X wmove(stw, 0, 0); X wprintw(stw, " Snake"); X refresh(); X barrier(barrier_skill,tv,stw); X wrefresh(stw); X wrefresh(tv); X life(); /* Create the snake */ X prize(); /* Put up a goal */ X for (;;) X { X if (running) X { X running--; X process(lastch); X } X else X { X fflush(stdout); X if (read(0, &ch, 1) >= 0) X process(ch); X } X } X} X Xlife() X{ X register struct body *bp, *np; X register int i; X X head = newlink(); X head->x = start_len+2; X head->y = 12; X head->next = NULL; X display(head, HEAD); X for (i = 0, bp = head; i < start_len; i++, bp = np) { X np = newlink(); X np->next = bp; X bp->prev = np; X np->x = bp->x - 1; X np->y = bp->y; X display(np, '-'); X } X display(np,' '); X display(np->next,' '); X tail = np; X tail->prev = NULL; X wrefresh(tv); X} X Xdisplay(pos, chr) Xstruct body *pos; Xchar chr; X{ X wmove(tv, pos->y, pos->x); X waddch(tv, chr); X} X Xleave() X{ X move(LINES - 1, 0); X refresh(); X endwin(); X exit(0); X} X Xwake() X{ X signal(SIGALRM, wake); X fflush(stdout); X process(lastch); X} X Xrnd(range) X{ X return abs((rand()>>5)+(rand()>>5)) % range; X} X Xnewpos(bp) Xstruct body * bp; X{ X do { X bp->y = rnd(LINES-3)+ 2; X bp->x = rnd(COLS-3) + 1; X wmove(tv, bp->y, bp->x); X } while(winch(tv) != ' '); X} X Xprize() X{ X int value; X X value = rnd(9) + 1; X newpos(&goody); X waddch(tv, value+'0'); X wrefresh(tv); X} X Xprocess(ch) Xchar ch; X{ X register int x,y; X struct body *nh; X static char headchar; X X alarm(0); X x = head->x; X y = head->y; X pd = dir; X switch(ch) X { X when 'h': x--; dir=LEFT; X { X if(pd==LEFT || pd==RIGHT) twist='-'; X if (pd==UP) twist='\\'; X if (pd==DOWN) twist='/';}; X when 'j': y++; dir=DOWN; twist='|'; X { if (pd==UP || pd==DOWN) twist='|'; X if (pd==LEFT) twist='/'; X if (pd==RIGHT) twist='\\';}; X when 'k': y--; dir=UP; twist ='|'; X { if (pd==UP || pd==DOWN) twist='|'; X if (pd==LEFT) twist='\\'; X if (pd==RIGHT) twist='/';}; X when 'l': x++; dir=RIGHT; twist ='-'; X { if (pd==LEFT || pd==RIGHT) twist='-'; X if (pd==UP) twist='/'; X if (pd==DOWN) twist='\\';}; X when 'H': x--; running = RUNLEN; ch = tolower(ch);dir=LEFT; X { if (pd==LEFT || pd==RIGHT) twist='-'; X if (pd==UP) twist='\\'; X if (pd==DOWN) twist='/';} X when 'J': y++; running = RUNLEN/2; ch = tolower(ch);dir=DOWN; X { if (pd==UP || pd==DOWN) twist='|'; X if (pd==LEFT) twist='/'; X if (pd==RIGHT) twist='\\';} X when 'K': y--; running = RUNLEN/2; ch = tolower(ch);dir=UP; X { if (pd==UP || pd==DOWN) twist='|'; X if (pd==LEFT) twist='\\'; X if (pd==RIGHT) twist='/';} X when 'L': x++; running = RUNLEN; ch = tolower(ch);dir=RIGHT; X { if (pd==LEFT || pd==RIGHT) twist='-'; X if (pd==UP) twist='/'; X if (pd==DOWN) twist='\\';}; X when '\f': setup(); return; X when CNTRL(Z): suspend(); return; X when CNTRL(C): exit_gracefully(); return; X when CNTRL(D): exit_gracefully(); return; X otherwise: if (! running) alarm(1); X return; X } X lastch = ch; X if (growing <= 0) X { X tail->next->prev = NULL; X nh = tail->next; X free(tail); X tail = nh; X if (growing < 0) X growing = 0; X display(tail->next,' '); X } X else growing--; X display(head,twist); X wmove(tv, y, x); X if (isdigit(ch = winch(tv))) X { X growing += ch-'0'; X prize(); X score += (growing*skill_level); X growing = grow_rate * growing; X running = 0; X wmove(stw, 0, 68); X wprintw(stw, "Score: %3d", score); X wrefresh(stw); X } X else if(ch != ' ') crash(); X nh = newlink(); X nh->next = NULL; X nh->prev = head; X head->next = nh; X nh->y = y; X nh->x = x; X switch (dir) { X case UP: X headchar = '^'; break; X case DOWN: X headchar = 'V'; break; X case LEFT: X headchar = '<' ; break; X case RIGHT: X headchar = '>' ; break; X default: X headchar = HEAD ; X } X display(nh, headchar); X head = nh; X wrefresh(tv); X if (! running) alarm(1); X} X Xcrash() X{ X clear(); X move(LINES - 1, 0); X refresh(); X endwin(); X fflush(stdout); X printf("Well you ran into something and the game is over.\n"); X printf("Your final score was %d\n", score); X leave(); X} Xexit_gracefully () X{ X clear(); X move(LINES - 1,0); X refresh(); X endwin(); X fflush(stdout); X printf("You quit with %d points.\n",score); X leave(); X} X Xsuspend() X{ X char *sh; X X move(LINES-1, 0); X refresh(); X endwin(); X fflush(stdout); X#ifdef SIGTSTP X kill(getpid(), SIGTSTP); X signal(SIGTSTP, suspend); X#else X sh = getenv("SHELL"); X if (sh == NULL) X sh = "/bin/sh"; X system(sh); X#endif X crmode(); X noecho(); X setup(); X} X Xsetup() X{ X clear(); X refresh(); X touchwin(stw); X wrefresh(stw); X touchwin(tv); X wrefresh(tv); X alarm(1); X} Xbarrier(skill,tv,stw) X WINDOW *tv,*stw; X int skill; X { X int i,j=0; X switch(skill) X { X case 1: break; X case 2: for (i=COLS/5;i<4*COLS/5;++i) X { X for (j=2*LINES/5;j<3*LINES/5;++j) X { X barrier_print(j,i,tv,stw); X } X }; X break; X case 3: for (i=2*COLS/5;i<3*COLS/5;++i) X { X for (j=LINES/5;j<4*LINES/5;++j) X { X barrier_print(j,i,tv,stw); X } X }; X for (i=COLS/5;i<4*COLS/5;++i) X { for (j=2*LINES/5;j<3*LINES/5;++j) X { barrier_print(j,i,tv,stw);}}; X break; X case 4: for (j=LINES/7;j<3*LINES/7;++j) X { for (i=1*COLS/7;i<2*COLS/7;i++) X { barrier_print(j,i,tv,stw);}; X for (i=5*COLS/7;i<6*COLS/7;++i) X { barrier_print(j,i,tv,stw);};}; X for (j=4*LINES/7;j<6*LINES/7;++j) X { for (i=1*COLS/7;i<2*COLS/7;++i) X { barrier_print(j,i,tv,stw);}; X for (i=5*COLS/7;i<6*COLS/7;++i) X { barrier_print(j,i,tv,stw);};}; X for (j=2*LINES/7;j<3*LINES/7;++j) X for (i=4*COLS/7;i<5*COLS/7;++i) X barrier_print(j,i,tv,stw); X for (j=4*LINES/7;j<5*LINES/7;++j) X for (i=2*COLS/7;i<3*COLS/7;++i) X barrier_print(j,i,tv,stw); X break; X }; X} Xbarrier_print(j,i,tv,stw) Xint j,i; XWINDOW *tv,*stw; X{ X wmove(tv,j,i); X wmove(stw,j,i); X waddch(tv,'*'); X waddch(stw,'*'); X} --End_of_snake2.c-- if test 9505 -ne `wc -c < 'snake2.c'` then echo "`basename $0`: error in" 'snake2.c' ": sent 9505 chars, received `wc -c < 'snake2.c'`" 1>&2 fi fi exit -- Mark Wutka Office of Computing Services Georgia Institute of Technology Atlanta, Ga. ...!{akgua,allegra,amd,hplabs,ihnp4,masscomp,ut-ngp}!gatech!gitpyr!wutka ...!{rlgvax,sb1,uf-cgrl,unmvax,ut-sally}!gatech!gitpyr!wutka Official member of NERDS (NERDS Existing in a Recursively Defined System)