]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - worm/worm.c
Remove incorrect (but unused) definition of baudrate().
[bsdgames-darwin.git] / worm / worm.c
1 /* $NetBSD: worm.c,v 1.7 1995/04/29 01:12:41 mycroft Exp $ */
2
3 /*
4 * Copyright (c) 1980, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #ifndef lint
37 static char copyright[] =
38 "@(#) Copyright (c) 1980, 1993\n\
39 The Regents of the University of California. All rights reserved.\n";
40 #endif /* not lint */
41
42 #ifndef lint
43 #if 0
44 static char sccsid[] = "@(#)worm.c 8.1 (Berkeley) 5/31/93";
45 #else
46 static char rcsid[] = "$NetBSD: worm.c,v 1.7 1995/04/29 01:12:41 mycroft Exp $";
47 #endif
48 #endif /* not lint */
49
50 /*
51 * Worm. Written by Michael Toy
52 * UCSC
53 */
54
55 #include <ctype.h>
56 #include <curses.h>
57 #include <signal.h>
58 #include <stdlib.h>
59 #include <termios.h>
60
61 #define newlink() (struct body *) malloc(sizeof (struct body));
62 #define HEAD '@'
63 #define BODY 'o'
64 #define LENGTH 7
65 #define RUNLEN 8
66 #define CNTRL(p) (p-'A'+1)
67
68 WINDOW *tv;
69 WINDOW *stw;
70 struct body {
71 int x;
72 int y;
73 struct body *prev;
74 struct body *next;
75 } *head, *tail, goody;
76 int growing = 0;
77 int running = 0;
78 int slow = 0;
79 int score = 0;
80 int start_len = LENGTH;
81 char lastch;
82 char outbuf[BUFSIZ];
83
84 void leave(), wake(), suspend();
85
86 main(argc, argv)
87 int argc;
88 char **argv;
89 {
90 char ch;
91
92 if (argc == 2)
93 start_len = atoi(argv[1]);
94 if ((start_len <= 0) || (start_len > 500))
95 start_len = LENGTH;
96 setbuf(stdout, outbuf);
97 srand(getpid());
98 signal(SIGALRM, wake);
99 signal(SIGINT, leave);
100 signal(SIGQUIT, leave);
101 signal(SIGTSTP, suspend); /* process control signal */
102 initscr();
103 crmode();
104 noecho();
105 slow = (baudrate() <= 1200);
106 clear();
107 stw = newwin(1, COLS-1, 0, 0);
108 tv = newwin(LINES-1, COLS-1, 1, 0);
109 box(tv, '*', '*');
110 scrollok(tv, FALSE);
111 scrollok(stw, FALSE);
112 wmove(stw, 0, 0);
113 wprintw(stw, " Worm");
114 refresh();
115 wrefresh(stw);
116 wrefresh(tv);
117 life(); /* Create the worm */
118 prize(); /* Put up a goal */
119 while(1)
120 {
121 if (running)
122 {
123 running--;
124 process(lastch);
125 }
126 else
127 {
128 fflush(stdout);
129 if (read(0, &ch, 1) >= 0)
130 process(ch);
131 }
132 }
133 }
134
135 life()
136 {
137 register struct body *bp, *np;
138 register int i;
139
140 head = newlink();
141 head->x = start_len+2;
142 head->y = 12;
143 head->next = NULL;
144 display(head, HEAD);
145 for (i = 0, bp = head; i < start_len; i++, bp = np) {
146 np = newlink();
147 np->next = bp;
148 bp->prev = np;
149 np->x = bp->x - 1;
150 np->y = bp->y;
151 display(np, BODY);
152 }
153 tail = np;
154 tail->prev = NULL;
155 }
156
157 display(pos, chr)
158 struct body *pos;
159 char chr;
160 {
161 wmove(tv, pos->y, pos->x);
162 waddch(tv, chr);
163 }
164
165 void
166 leave()
167 {
168 endwin();
169 exit(0);
170 }
171
172 void
173 wake()
174 {
175 signal(SIGALRM, wake);
176 fflush(stdout);
177 process(lastch);
178 }
179
180 rnd(range)
181 {
182 return abs((rand()>>5)+(rand()>>5)) % range;
183 }
184
185 newpos(bp)
186 struct body * bp;
187 {
188 do {
189 bp->y = rnd(LINES-3)+ 2;
190 bp->x = rnd(COLS-3) + 1;
191 wmove(tv, bp->y, bp->x);
192 } while(winch(tv) != ' ');
193 }
194
195 prize()
196 {
197 int value;
198
199 value = rnd(9) + 1;
200 newpos(&goody);
201 waddch(tv, value+'0');
202 wrefresh(tv);
203 }
204
205 process(ch)
206 char ch;
207 {
208 register int x,y;
209 struct body *nh;
210
211 alarm(0);
212 x = head->x;
213 y = head->y;
214 switch(ch)
215 {
216 case 'h': x--; break;
217 case 'j': y++; break;
218 case 'k': y--; break;
219 case 'l': x++; break;
220 case 'H': x--; running = RUNLEN; ch = tolower(ch); break;
221 case 'J': y++; running = RUNLEN/2; ch = tolower(ch); break;
222 case 'K': y--; running = RUNLEN/2; ch = tolower(ch); break;
223 case 'L': x++; running = RUNLEN; ch = tolower(ch); break;
224 case '\f': setup(); return;
225 case CNTRL('Z'): suspend(); return;
226 case CNTRL('C'): crash(); return;
227 case CNTRL('D'): crash(); return;
228 default: if (! running) alarm(1);
229 return;
230 }
231 lastch = ch;
232 if (growing == 0)
233 {
234 display(tail, ' ');
235 tail->next->prev = NULL;
236 nh = tail->next;
237 free(tail);
238 tail = nh;
239 }
240 else growing--;
241 display(head, BODY);
242 wmove(tv, y, x);
243 if (isdigit(ch = winch(tv)))
244 {
245 growing += ch-'0';
246 prize();
247 score += growing;
248 running = 0;
249 wmove(stw, 0, 68);
250 wprintw(stw, "Score: %3d", score);
251 wrefresh(stw);
252 }
253 else if(ch != ' ') crash();
254 nh = newlink();
255 nh->next = NULL;
256 nh->prev = head;
257 head->next = nh;
258 nh->y = y;
259 nh->x = x;
260 display(nh, HEAD);
261 head = nh;
262 if (!(slow && running))
263 wrefresh(tv);
264 if (!running)
265 alarm(1);
266 }
267
268 crash()
269 {
270 sleep(2);
271 clear();
272 move(23, 0);
273 refresh();
274 printf("Well, you ran into something and the game is over.\n");
275 printf("Your final score was %d\n", score);
276 leave();
277 }
278
279 void
280 suspend()
281 {
282 char *sh;
283
284 move(LINES-1, 0);
285 refresh();
286 endwin();
287 fflush(stdout);
288 kill(getpid(), SIGTSTP);
289 signal(SIGTSTP, suspend);
290 crmode();
291 noecho();
292 setup();
293 }
294
295 setup()
296 {
297 clear();
298 refresh();
299 touchwin(stw);
300 wrefresh(stw);
301 touchwin(tv);
302 wrefresh(tv);
303 alarm(1);
304 }