|
|
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 the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #ifndef lint ! 19: char copyright[] = ! 20: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ ! 21: All rights reserved.\n"; ! 22: #endif /* not lint */ ! 23: ! 24: #ifndef lint ! 25: static char sccsid[] = "@(#)worm.c 5.5 (Berkeley) 6/27/88"; ! 26: #endif /* not lint */ ! 27: ! 28: /* ! 29: * Worm. Written by Michael Toy ! 30: * UCSC ! 31: */ ! 32: ! 33: #include <ctype.h> ! 34: #include <curses.h> ! 35: #include <signal.h> ! 36: ! 37: #define newlink() (struct body *) malloc(sizeof (struct body)); ! 38: #define HEAD '@' ! 39: #define BODY 'o' ! 40: #define LENGTH 7 ! 41: #define RUNLEN 8 ! 42: #define when break;case ! 43: #define otherwise break;default ! 44: #define CNTRL(p) (p-'A'+1) ! 45: #ifndef baudrate ! 46: # define baudrate() _tty.sg_ospeed ! 47: #endif ! 48: ! 49: WINDOW *tv; ! 50: WINDOW *stw; ! 51: struct body { ! 52: int x; ! 53: int y; ! 54: struct body *prev; ! 55: struct body *next; ! 56: } *head, *tail, goody; ! 57: int growing = 0; ! 58: int running = 0; ! 59: int slow = 0; ! 60: int score = 0; ! 61: int start_len = LENGTH; ! 62: char lastch; ! 63: char outbuf[BUFSIZ]; ! 64: ! 65: main(argc, argv) ! 66: char **argv; ! 67: { ! 68: int leave(), wake(), suspend(); ! 69: char ch; ! 70: ! 71: if (argc == 2) ! 72: start_len = atoi(argv[1]); ! 73: if ((start_len <= 0) || (start_len > 500)) ! 74: start_len = LENGTH; ! 75: setbuf(stdout, outbuf); ! 76: srand(getpid()); ! 77: signal(SIGALRM, wake); ! 78: signal(SIGINT, leave); ! 79: signal(SIGQUIT, leave); ! 80: #ifdef SIGTSTP ! 81: signal(SIGTSTP, suspend); /* process control signal */ ! 82: #endif ! 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: #ifdef SIGTSTP ! 267: kill(getpid(), SIGTSTP); ! 268: signal(SIGTSTP, suspend); ! 269: #else ! 270: sh = getenv("SHELL"); ! 271: if (sh == NULL) ! 272: sh = "/bin/sh"; ! 273: system(sh); ! 274: #endif ! 275: crmode(); ! 276: noecho(); ! 277: setup(); ! 278: } ! 279: ! 280: setup() ! 281: { ! 282: clear(); ! 283: refresh(); ! 284: touchwin(stw); ! 285: wrefresh(stw); ! 286: touchwin(tv); ! 287: wrefresh(tv); ! 288: alarm(1); ! 289: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.