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