|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 9505 (0x2521)
Types: TextFile
Names: »snake2.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Snake/snake2.c«
/*
* 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
* barriers and double-elongation added by Mark Wutka
* Office of Computing Services
* Georgia Institute of Technology
*
* 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 skill_level =1;
char sl;
int barrier_skill = 0;
int start_len = LENGTH;
int pd=RIGHT;
int dir=RIGHT;
int grow_rate = 1;
char twist;
char lastch;
char outbuf[BUFSIZ];
main(argc, argv)
char **argv;
{
int leave(), wake(), suspend();
char ch;
if (argc == 2)
{
skill_level=atoi(argv[1]);
}
else
{
printf("Format for running snake:\n");
printf("snake n\n");
printf("where n= the skill level (1-4)\n");
exit(0);
};
if(skill_level<1) skill_level=1;
if(skill_level>4) skill_level=4;
switch(skill_level)
{
case 1:
start_len=7;
grow_rate=1;
barrier_skill = 1;
break;
case 2:
start_len=10;
grow_rate=1;
barrier_skill = 2;
break;
case 3:
start_len=10;
grow_rate=2;
barrier_skill=3;
break;
case 4:
start_len=15;
grow_rate=2;
barrier_skill=4;
break;
};
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();
barrier(barrier_skill,tv,stw);
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, '-');
}
display(np,' ');
display(np->next,' ');
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;
alarm(0);
x = head->x;
y = head->y;
pd = dir;
switch(ch)
{
when 'h': x--; dir=LEFT;
{
if(pd==LEFT || pd==RIGHT) twist='-';
if (pd==UP) twist='\\';
if (pd==DOWN) twist='/';};
when 'j': y++; dir=DOWN; twist='|';
{ if (pd==UP || pd==DOWN) twist='|';
if (pd==LEFT) twist='/';
if (pd==RIGHT) twist='\\';};
when 'k': y--; dir=UP; twist ='|';
{ if (pd==UP || pd==DOWN) twist='|';
if (pd==LEFT) twist='\\';
if (pd==RIGHT) twist='/';};
when 'l': x++; dir=RIGHT; twist ='-';
{ if (pd==LEFT || pd==RIGHT) twist='-';
if (pd==UP) twist='/';
if (pd==DOWN) twist='\\';};
when 'H': x--; running = RUNLEN; ch = tolower(ch);dir=LEFT;
{ if (pd==LEFT || pd==RIGHT) twist='-';
if (pd==UP) twist='\\';
if (pd==DOWN) twist='/';}
when 'J': y++; running = RUNLEN/2; ch = tolower(ch);dir=DOWN;
{ if (pd==UP || pd==DOWN) twist='|';
if (pd==LEFT) twist='/';
if (pd==RIGHT) twist='\\';}
when 'K': y--; running = RUNLEN/2; ch = tolower(ch);dir=UP;
{ if (pd==UP || pd==DOWN) twist='|';
if (pd==LEFT) twist='\\';
if (pd==RIGHT) twist='/';}
when 'L': x++; running = RUNLEN; ch = tolower(ch);dir=RIGHT;
{ if (pd==LEFT || pd==RIGHT) twist='-';
if (pd==UP) twist='/';
if (pd==DOWN) twist='\\';};
when '\f': setup(); return;
when CNTRL(Z): suspend(); return;
when CNTRL(C): exit_gracefully(); return;
when CNTRL(D): exit_gracefully(); return;
otherwise: if (! running) alarm(1);
return;
}
lastch = ch;
if (growing <= 0)
{
tail->next->prev = NULL;
nh = tail->next;
free(tail);
tail = nh;
if (growing < 0)
growing = 0;
display(tail->next,' ');
}
else growing--;
display(head,twist);
wmove(tv, y, x);
if (isdigit(ch = winch(tv)))
{
growing += ch-'0';
prize();
score += (growing*skill_level);
growing = grow_rate * 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()
{
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();
}
exit_gracefully ()
{
clear();
move(LINES - 1,0);
refresh();
endwin();
fflush(stdout);
printf("You quit with %d points.\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);
}
barrier(skill,tv,stw)
WINDOW *tv,*stw;
int skill;
{
int i,j=0;
switch(skill)
{
case 1: break;
case 2: for (i=COLS/5;i<4*COLS/5;++i)
{
for (j=2*LINES/5;j<3*LINES/5;++j)
{
barrier_print(j,i,tv,stw);
}
};
break;
case 3: for (i=2*COLS/5;i<3*COLS/5;++i)
{
for (j=LINES/5;j<4*LINES/5;++j)
{
barrier_print(j,i,tv,stw);
}
};
for (i=COLS/5;i<4*COLS/5;++i)
{ for (j=2*LINES/5;j<3*LINES/5;++j)
{ barrier_print(j,i,tv,stw);}};
break;
case 4: for (j=LINES/7;j<3*LINES/7;++j)
{ for (i=1*COLS/7;i<2*COLS/7;i++)
{ barrier_print(j,i,tv,stw);};
for (i=5*COLS/7;i<6*COLS/7;++i)
{ barrier_print(j,i,tv,stw);};};
for (j=4*LINES/7;j<6*LINES/7;++j)
{ for (i=1*COLS/7;i<2*COLS/7;++i)
{ barrier_print(j,i,tv,stw);};
for (i=5*COLS/7;i<6*COLS/7;++i)
{ barrier_print(j,i,tv,stw);};};
for (j=2*LINES/7;j<3*LINES/7;++j)
for (i=4*COLS/7;i<5*COLS/7;++i)
barrier_print(j,i,tv,stw);
for (j=4*LINES/7;j<5*LINES/7;++j)
for (i=2*COLS/7;i<3*COLS/7;++i)
barrier_print(j,i,tv,stw);
break;
};
}
barrier_print(j,i,tv,stw)
int j,i;
WINDOW *tv,*stw;
{
wmove(tv,j,i);
wmove(stw,j,i);
waddch(tv,'*');
waddch(stw,'*');
}