new mbuf stats
[unix-history] / usr / src / games / worm / worm.c
CommitLineData
c4e6edfa
KM
1
2static char sccsid[] = " worm.c 4.1 82/10/24 ";
3
4/*
5 * Worm. Written by Michael Toy
6 * UCSC
7 */
8
9#include <ctype.h>
10#include <curses.h>
11#include <signal.h>
12
13#define newlink() (struct body *) malloc(sizeof (struct body));
14#define HEAD '@'
15#define BODY 'o'
16#define LENGTH 7
17#define RUNLEN 8
18#define when break;case
19#define otherwise break;default
20#define CNTRL(p) ('p'-'A'+1)
21
22WINDOW *tv;
23WINDOW *stw;
24struct body {
25 int x;
26 int y;
27 struct body *prev;
28 struct body *next;
29} *head, *tail, goody;
30int growing = 0;
31int running = 0;
32int score = 0;
33int start_len = LENGTH;
34char lastch;
35char outbuf[BUFSIZ];
36
37main(argc, argv)
38char **argv;
39{
40 int leave(), wake(), suspend();
41 char ch;
42
43 if (argc == 2)
44 start_len = atoi(argv[1]);
45 if ((start_len <= 0) || (start_len > 500))
46 start_len = LENGTH;
47 setbuf(stdout, outbuf);
48 srand(getpid());
49 signal(SIGALRM, wake);
50 signal(SIGINT, leave);
51 signal(SIGQUIT, leave);
52#ifdef SIGTSTP
53 signal(SIGTSTP, suspend); /* process control signal */
54#endif
55 initscr();
56 crmode();
57 noecho();
58 clear();
59 stw = newwin(1, COLS-1, 0, 0);
60 tv = newwin(LINES-1, COLS-1, 1, 0);
61 box(tv, '*', '*');
62 scrollok(tv, FALSE);
63 scrollok(stw, FALSE);
64 wmove(stw, 0, 0);
65 wprintw(stw, " Worm");
66 refresh();
67 wrefresh(stw);
68 wrefresh(tv);
69 life(); /* Create the worm */
70 prize(); /* Put up a goal */
71 while(1)
72 {
73 if (running)
74 {
75 running--;
76 process(lastch);
77 }
78 else
79 {
80 fflush(stdout);
81 if (read(0, &ch, 1) >= 0)
82 process(ch);
83 }
84 }
85}
86
87life()
88{
89 register struct body *bp, *np;
90 register int i;
91
92 head = newlink();
93 head->x = start_len+2;
94 head->y = 12;
95 head->next = NULL;
96 display(head, HEAD);
97 for (i = 0, bp = head; i < start_len; i++, bp = np) {
98 np = newlink();
99 np->next = bp;
100 bp->prev = np;
101 np->x = bp->x - 1;
102 np->y = bp->y;
103 display(np, BODY);
104 }
105 tail = np;
106 tail->prev = NULL;
107 wrefresh(tv);
108}
109
110display(pos, chr)
111struct body *pos;
112char chr;
113{
114 wmove(tv, pos->y, pos->x);
115 waddch(tv, chr);
116}
117
118leave()
119{
120 endwin();
121 exit(0);
122}
123
124wake()
125{
126 signal(SIGALRM, wake);
127 fflush(stdout);
128 process(lastch);
129}
130
131rnd(range)
132{
133 return abs((rand()>>5)+(rand()>>5)) % range;
134}
135
136newpos(bp)
137struct body * bp;
138{
139 do {
140 bp->y = rnd(LINES-3)+ 2;
141 bp->x = rnd(COLS-3) + 1;
142 wmove(tv, bp->y, bp->x);
143 } while(winch(tv) != ' ');
144}
145
146prize()
147{
148 int value;
149
150 value = rnd(9) + 1;
151 newpos(&goody);
152 waddch(tv, value+'0');
153 wrefresh(tv);
154}
155
156process(ch)
157char ch;
158{
159 register int x,y;
160 struct body *nh;
161
162 alarm(0);
163 x = head->x;
164 y = head->y;
165 switch(ch)
166 {
167 when 'h': x--;
168 when 'j': y++;
169 when 'k': y--;
170 when 'l': x++;
171 when 'H': x--; running = RUNLEN; ch = tolower(ch);
172 when 'J': y++; running = RUNLEN/2; ch = tolower(ch);
173 when 'K': y--; running = RUNLEN/2; ch = tolower(ch);
174 when 'L': x++; running = RUNLEN; ch = tolower(ch);
175 when '\f': setup(); return;
176 when CNTRL(Z): suspend(); return;
177 when CNTRL(C): crash(); return;
178 when CNTRL(D): crash(); return;
179 otherwise: if (! running) alarm(1);
180 return;
181 }
182 lastch = ch;
183 if (growing == 0)
184 {
185 display(tail, ' ');
186 tail->next->prev = NULL;
187 nh = tail->next;
188 free(tail);
189 tail = nh;
190 }
191 else growing--;
192 display(head, BODY);
193 wmove(tv, y, x);
194 if (isdigit(ch = winch(tv)))
195 {
196 growing += ch-'0';
197 prize();
198 score += growing;
199 running = 0;
200 wmove(stw, 0, 68);
201 wprintw(stw, "Score: %3d", score);
202 wrefresh(stw);
203 }
204 else if(ch != ' ') crash();
205 nh = newlink();
206 nh->next = NULL;
207 nh->prev = head;
208 head->next = nh;
209 nh->y = y;
210 nh->x = x;
211 display(nh, HEAD);
212 head = nh;
213 wrefresh(tv);
214 if (! running) alarm(1);
215}
216
217crash()
218{
219 sleep(2);
220 clear();
221 move(23, 0);
222 refresh();
223 printf("Well you ran into something and the game is over.\n");
224 printf("Your final score was %d\n", score);
225 leave();
226}
227
228suspend()
229{
230 char *sh;
231
232 move(LINES-1, 0);
233 refresh();
234 endwin();
235 fflush(stdout);
236#ifdef SIGTSTP
237 kill(getpid(), SIGTSTP);
238 signal(SIGTSTP, suspend);
239#else
240 sh = getenv("SHELL");
241 if (sh == NULL)
242 sh = "/bin/sh";
243 system(sh);
244#endif
245 crmode();
246 noecho();
247 setup();
248}
249
250setup()
251{
252 clear();
253 refresh();
254 touchwin(stw);
255 wrefresh(stw);
256 touchwin(tv);
257 wrefresh(tv);
258 alarm(1);
259}