|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: char copyright[] =
22: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
23: All rights reserved.\n";
24: #endif /* not lint */
25:
26: #ifndef lint
27: static char sccsid[] = "@(#)worm.c 5.7 (Berkeley) 6/1/90";
28: #endif /* not lint */
29:
30: /*
31: * Worm. Written by Michael Toy
32: * UCSC
33: */
34:
35: #include <ctype.h>
36: #include <curses.h>
37: #include <signal.h>
38:
39: #define newlink() (struct body *) malloc(sizeof (struct body));
40: #define HEAD '@'
41: #define BODY 'o'
42: #define LENGTH 7
43: #define RUNLEN 8
44: #define when break;case
45: #define otherwise break;default
46: #define CNTRL(p) (p-'A'+1)
47: #ifndef baudrate
48: # define baudrate() _tty.sg_ospeed
49: #endif
50:
51: WINDOW *tv;
52: WINDOW *stw;
53: struct body {
54: int x;
55: int y;
56: struct body *prev;
57: struct body *next;
58: } *head, *tail, goody;
59: int growing = 0;
60: int running = 0;
61: int slow = 0;
62: int score = 0;
63: int start_len = LENGTH;
64: char lastch;
65: char outbuf[BUFSIZ];
66:
67: main(argc, argv)
68: char **argv;
69: {
70: int leave(), wake(), suspend();
71: char ch;
72:
73: if (argc == 2)
74: start_len = atoi(argv[1]);
75: if ((start_len <= 0) || (start_len > 500))
76: start_len = LENGTH;
77: setbuf(stdout, outbuf);
78: srand(getpid());
79: signal(SIGALRM, wake);
80: signal(SIGINT, leave);
81: signal(SIGQUIT, leave);
82: signal(SIGTSTP, suspend); /* process control signal */
83: initscr();
84: crmode();
85: noecho();
86: slow = (baudrate() <= B1200);
87: clear();
88: stw = newwin(1, COLS-1, 0, 0);
89: tv = newwin(LINES-1, COLS-1, 1, 0);
90: box(tv, '*', '*');
91: scrollok(tv, FALSE);
92: scrollok(stw, FALSE);
93: wmove(stw, 0, 0);
94: wprintw(stw, " Worm");
95: refresh();
96: wrefresh(stw);
97: wrefresh(tv);
98: life(); /* Create the worm */
99: prize(); /* Put up a goal */
100: while(1)
101: {
102: if (running)
103: {
104: running--;
105: process(lastch);
106: }
107: else
108: {
109: fflush(stdout);
110: if (read(0, &ch, 1) >= 0)
111: process(ch);
112: }
113: }
114: }
115:
116: life()
117: {
118: register struct body *bp, *np;
119: register int i;
120:
121: head = newlink();
122: head->x = start_len+2;
123: head->y = 12;
124: head->next = NULL;
125: display(head, HEAD);
126: for (i = 0, bp = head; i < start_len; i++, bp = np) {
127: np = newlink();
128: np->next = bp;
129: bp->prev = np;
130: np->x = bp->x - 1;
131: np->y = bp->y;
132: display(np, BODY);
133: }
134: tail = np;
135: tail->prev = NULL;
136: }
137:
138: display(pos, chr)
139: struct body *pos;
140: char chr;
141: {
142: wmove(tv, pos->y, pos->x);
143: waddch(tv, chr);
144: }
145:
146: leave()
147: {
148: endwin();
149: exit(0);
150: }
151:
152: wake()
153: {
154: signal(SIGALRM, wake);
155: fflush(stdout);
156: process(lastch);
157: }
158:
159: rnd(range)
160: {
161: return abs((rand()>>5)+(rand()>>5)) % range;
162: }
163:
164: newpos(bp)
165: struct body * bp;
166: {
167: do {
168: bp->y = rnd(LINES-3)+ 2;
169: bp->x = rnd(COLS-3) + 1;
170: wmove(tv, bp->y, bp->x);
171: } while(winch(tv) != ' ');
172: }
173:
174: prize()
175: {
176: int value;
177:
178: value = rnd(9) + 1;
179: newpos(&goody);
180: waddch(tv, value+'0');
181: wrefresh(tv);
182: }
183:
184: process(ch)
185: char ch;
186: {
187: register int x,y;
188: struct body *nh;
189:
190: alarm(0);
191: x = head->x;
192: y = head->y;
193: switch(ch)
194: {
195: when 'h': x--;
196: when 'j': y++;
197: when 'k': y--;
198: when 'l': x++;
199: when 'H': x--; running = RUNLEN; ch = tolower(ch);
200: when 'J': y++; running = RUNLEN/2; ch = tolower(ch);
201: when 'K': y--; running = RUNLEN/2; ch = tolower(ch);
202: when 'L': x++; running = RUNLEN; ch = tolower(ch);
203: when '\f': setup(); return;
204: when CNTRL('Z'): suspend(); return;
205: when CNTRL('C'): crash(); return;
206: when CNTRL('D'): crash(); return;
207: otherwise: if (! running) alarm(1);
208: return;
209: }
210: lastch = ch;
211: if (growing == 0)
212: {
213: display(tail, ' ');
214: tail->next->prev = NULL;
215: nh = tail->next;
216: free(tail);
217: tail = nh;
218: }
219: else growing--;
220: display(head, BODY);
221: wmove(tv, y, x);
222: if (isdigit(ch = winch(tv)))
223: {
224: growing += ch-'0';
225: prize();
226: score += growing;
227: running = 0;
228: wmove(stw, 0, 68);
229: wprintw(stw, "Score: %3d", score);
230: wrefresh(stw);
231: }
232: else if(ch != ' ') crash();
233: nh = newlink();
234: nh->next = NULL;
235: nh->prev = head;
236: head->next = nh;
237: nh->y = y;
238: nh->x = x;
239: display(nh, HEAD);
240: head = nh;
241: if (!(slow && running))
242: wrefresh(tv);
243: if (!running)
244: alarm(1);
245: }
246:
247: crash()
248: {
249: sleep(2);
250: clear();
251: move(23, 0);
252: refresh();
253: printf("Well, you ran into something and the game is over.\n");
254: printf("Your final score was %d\n", score);
255: leave();
256: }
257:
258: suspend()
259: {
260: char *sh;
261:
262: move(LINES-1, 0);
263: refresh();
264: endwin();
265: fflush(stdout);
266: kill(getpid(), SIGTSTP);
267: signal(SIGTSTP, suspend);
268: crmode();
269: noecho();
270: setup();
271: }
272:
273: setup()
274: {
275: clear();
276: refresh();
277: touchwin(stw);
278: wrefresh(stw);
279: touchwin(tv);
280: wrefresh(tv);
281: alarm(1);
282: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.