|
|
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.