home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / games / worm / worm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-08  |  6.0 KB  |  302 lines

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