home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / TOP / USR / SRC / wanderer2.t.Z / wanderer2.t / game.c < prev    next >
C/C++ Source or Header  |  1988-11-23  |  21KB  |  897 lines

  1. #include "wand_head.h"
  2.  
  3. #define viable(x,y) (((screen[y][x] == ' ') || (screen[y][x] == ':') ||\
  4.     (screen[y][x] == '@') || (screen[y][x] == '+') ||\
  5.     (screen[y][x] == 'S')) && (y >= 0) &&\
  6.     (x >= 0) && (y < NOOFROWS) && (x < ROWLEN))
  7.  
  8. /* typedef struct mon_rec        *//* M002 struct mon_rec moved    */
  9. /*     {                *//* to header file because it     */
  10. /*     int x,y,mx,my;            *//* is needed by save.c    */
  11. /*     char under;            */
  12. /*     struct mon_rec *next,*prev;    */
  13. /*     };                */
  14.  
  15. typedef struct { int d[2] } direction;
  16.  
  17. #ifdef    LINT_ARGS    /* M001 */
  18. direction new_direction(int, int, int, int);
  19. #else
  20. direction new_direction();
  21. #endif
  22.  
  23. extern int jumpscreen();
  24.  
  25. extern int check();
  26.  
  27. extern void showpass();
  28.  
  29. extern void draw_symbol();
  30.  
  31. extern void display();
  32.  
  33. extern int fall();
  34.  
  35. extern void map();
  36.  
  37. extern void redraw_screen();
  38. extern int debug_disp;
  39. extern int edit_mode;
  40. extern int saved_game;
  41. extern char screen[NOOFROWS][ROWLEN+1];
  42.  
  43. /* Add a spirit to the chain */
  44. /* Maintain a doubly linked list to make reuse possible.
  45.    tail_of_list is *NOT* the last monster allocated, but
  46.    the last monster alloted to a screen.  start_of_list
  47.    is a dummy entry to ease processing. last_of_list
  48.    is the last entry allocated. */
  49. static struct mon_rec start_of_list = {0,0,0,0,0,NULL,NULL};
  50.  
  51. struct mon_rec *tail_of_list;
  52. struct mon_rec *last_of_list;
  53.  
  54. struct mon_rec *make_monster(x,y)
  55. int x,y;
  56. {
  57. char *malloc();
  58. #define MALLOC (struct mon_rec *)malloc(sizeof(struct mon_rec))
  59. struct mon_rec *monster;
  60. if(tail_of_list->next == NULL)
  61.     {
  62.     if((last_of_list = MALLOC) == NULL)
  63.     return NULL;
  64.     tail_of_list->next = last_of_list;
  65.     last_of_list->prev = tail_of_list;
  66.     last_of_list->next = NULL;
  67.     }
  68. monster = tail_of_list = tail_of_list->next;
  69. monster->x = x;
  70. monster->y = y;
  71. monster->mx = 1;      /* always start moving RIGHT. (fix later)  */
  72. monster->my = 0;
  73. monster->under = ' ';
  74. return monster;
  75. }
  76.  
  77. /* 'follow lefthand wall' algorithm for baby monsters */
  78.  
  79. direction new_direction(x,y,bx,by)
  80. int x,y,bx,by;
  81. {
  82. direction out;
  83. if(viable((x+by),(y-bx)))
  84.     {
  85.     out.d[0] = by;
  86.     out.d[1] = -bx;
  87.     return out;
  88.     }
  89. if(viable((x+bx),(y+by)))
  90.     {
  91.     out.d[0] = bx;
  92.     out.d[1] = by;
  93.     return out;
  94.     }
  95. if(viable((x-by),(y+bx)))
  96.     {
  97.     out.d[0] = -by;
  98.     out.d[1] = bx;
  99.     return out;
  100.     }
  101. if(viable((x-bx),(y-by)))
  102.     {
  103.     out.d[0] = -bx;
  104.     out.d[1] = -by;
  105.     return out;
  106.     }
  107. out.d[0] = -bx;
  108. out.d[1] = -by;
  109. return out;
  110. }
  111.  
  112. /* Actual game function - Calls fall() to move
  113.        boulders and arrows recursively */
  114. /* Variable explaination :
  115.     All the var names make sense to ME, but some people think them a bit confusing... :-) So heres an explanation.
  116.    x,y : where you are
  117.    nx,ny : where you're trying to move to
  118.    sx,sy : where the screen window on the playing area is
  119.    mx,my : where the monster is
  120.    tx,ty : teleport arrival
  121.    bx,by : baby monster position
  122.    nbx,nby : where it wants to be
  123.    lx,ly : the place you left when teleporting
  124.    nf : how many diamonds youve got so far
  125.    new_disp : the vector the baby monster is trying
  126. */
  127.  
  128. char *playscreen(num,score,bell,maxmoves,keys)
  129. int  *num, maxmoves,
  130.      *bell,
  131.      *score;
  132. char keys[10];
  133. {
  134. int  x,y,nx,ny,deadyet =0,
  135.      sx = -1,sy = -1,tx = -1,ty = -1,lx = 0,ly = 0,mx = -1,my = -1,
  136.      ch,
  137.      bx, by, nbx, nby, tmpx,tmpy,
  138.      newnum, moved,
  139.      max_score = 250,
  140.      diamonds = 0, nf = 0,hd ,vd ,xdirection,ydirection;
  141. char (*frow)[ROWLEN+1] = screen,
  142.      buffer[25];
  143. static char     howdead[25];    /* M001 can't use auto var for return value */
  144. direction new_disp;
  145. struct mon_rec *monster,*current;
  146.  
  147. tail_of_list = &start_of_list;
  148.  
  149. for(x=0;x<=ROWLEN;x++)
  150.     for(y=0;y<NOOFROWS;y++)
  151.     {
  152.     if((screen[y][x] == '*')||(screen[y][x] == '+'))
  153.         {
  154.         diamonds++;
  155.         max_score += 10;
  156.         if(screen[y][x] == '+')
  157.         max_score += 20;
  158.         }
  159.         if(screen[y][x] == 'A')     /* note teleport arrival point &  */
  160.         {                       /* replace with space */
  161.         tx = x;
  162.         ty = y;
  163.          screen[y][x] = ' ';
  164.         }
  165.         if(screen[y][x] == '@')
  166.         {
  167.         sx = x;
  168.         sy = y;
  169.         }
  170.         if(screen[y][x] == 'M')     /* Put megamonster in */
  171.         {
  172.         mx = x;
  173.         my = y;
  174.         }
  175.     if(screen[y][x] == 'S')     /* link small monster to pointer chain */
  176.         {
  177.         if((monster = make_monster(x,y)) == NULL)
  178.         {
  179.         strcpy(howdead,"running out of memory");
  180.         return howdead;
  181.         }
  182.         if(!viable(x,y-1))     /* make sure its running in the correct */
  183.         {                  /* direction..                          */
  184.         monster->mx = 1;
  185.         monster->my = 0;
  186.         }
  187.         else if(!viable(x+1,y))
  188.         {
  189.         monster->mx = 0;
  190.         monster->my = 1;
  191.         }
  192.         else if(!viable(x,y+1))
  193.         {
  194.         monster->mx = -1;
  195.         monster->my = 0;
  196.         }
  197.         else if(!viable(x-1,y))
  198.         {
  199.         monster->mx = 0;
  200.         monster->my = -1;
  201.         }
  202.         }
  203.         if(screen[y][x] == '-')
  204.             screen[y][x] = ' ';
  205.         };
  206. x=sx;
  207. y=sy;
  208. if((x == -1)&&(y == -1))              /* no start position in screen ? */
  209.     {
  210.     strcpy(howdead,"a screen design error");
  211.     return(howdead);
  212.     }
  213.  
  214. update_game:    /* M002  restored game restarts here    */
  215.  
  216. move(0,48);
  217. (void) addstr("Score\t   Diamonds");
  218. move(1,48);
  219. (void) addstr("\tFound\tTotal");
  220. move(3,48);
  221. (void) sprintf(buffer,"%d\t %d\t %d  ",*score,nf,diamonds);
  222. (void) addstr(buffer);
  223. move(6,48);
  224. (void) sprintf(buffer,"Current screen %d",*num);
  225. (void) addstr(buffer);
  226. if(maxmoves != 0)
  227. (void) sprintf(buffer,"Moves remaining = %d   ",maxmoves);
  228. else
  229. {
  230.     (void) strcpy(buffer,"     Unlimited moves     ");
  231.     maxmoves = -1;
  232. };
  233. move(15,48);
  234. (void) addstr(buffer);
  235. if(mx != -1)                            /* tell player if monster exists */
  236.     draw_symbol(48,10,'M');
  237. else
  238.     draw_symbol(48,10,' ');
  239.  
  240. if(!debug_disp)
  241.     display(sx,sy,frow,*score);
  242. else
  243.     map(frow);
  244.  
  245. /* ACTUAL GAME FUNCTION - Returns method of death in string  */
  246.  
  247. while(deadyet == 0)
  248. {
  249. ch = getch();
  250.  
  251. nx=x;
  252. ny=y;
  253.  
  254. if(ch == keys[3] || ch == KEY_RIGHT)              /* move about - but thats obvious */
  255.     nx++;
  256. if(ch == keys[2] || ch == KEY_LEFT || ch == KEY_BACKSPACE)
  257.     nx--;
  258. if((ch == keys[1] || ch == KEY_DOWN) && (y<(NOOFROWS-1)))
  259.     ny++;
  260. if(ch == keys[0] || ch == KEY_UP)
  261.         ny--;
  262. if(ch == '1')                  /* Add or get rid of that awful sound */
  263.     {
  264.         move(10,45);
  265.         *bell = 1;
  266.         (void) addstr("Bell ON ");
  267.     move(16,0);
  268.         refresh();
  269.     continue;
  270.     }
  271. if(ch == '0')
  272.     {
  273.         *bell = 0;
  274.         move(10,45);
  275.         (void) addstr("Bell OFF");
  276.     move(16,0);
  277.         refresh();
  278.     continue;
  279.     }
  280. if(ch == '~')                             /* level jump */
  281.     {
  282.     if((newnum = jumpscreen(*num)) == 0)
  283.         {
  284.         strcpy(howdead,"a jump error.");
  285.         return howdead;
  286.         }
  287.     if(newnum != *num)
  288.         {                  /* Sorry Greg, no points for free */
  289.         sprintf(howdead,"~%c",newnum);
  290.         return howdead;
  291.         }
  292.     continue;
  293.     }
  294. if(ch == '!')                      /* look at the map */
  295.     {
  296.     if(debug_disp)
  297.         continue;
  298.     map(frow);
  299.         display(sx,sy,frow,*score);
  300.     continue;
  301.     }
  302. if(ch == 'q')
  303.         {
  304.         strcpy(howdead,"quitting the game");
  305.     return howdead;
  306.     }
  307. if(ch == '?')
  308.     {
  309.     helpme();
  310.     display(sx,sy,frow,*score);
  311.     if(debug_disp)
  312.         map(frow);
  313.         else
  314.         display(sx,sy,frow,*score);
  315.     continue;
  316.     }
  317. if((ch == '@')&&(!debug_disp))
  318.     {
  319.     sx = x;
  320.     sy = y;
  321.     continue;
  322.     }
  323.  
  324. if(ch == '#')
  325.     {
  326.     debug_disp = 1 - debug_disp;
  327.     if(debug_disp)
  328.         map(frow);
  329.     else
  330.         {
  331.          for(tmpy=0;tmpy<=(NOOFROWS+1);tmpy++)
  332.                 {
  333.                 move(tmpy,0);
  334.                 for(tmpx=0;tmpx<=(ROWLEN+2);tmpx++)
  335.                     addch(' ');
  336.             }
  337.         sx = x; sy = y;
  338.         display(sx,sy,frow,*score);
  339.         }
  340.     continue;
  341.     }
  342. if(ch == 'W')
  343.     {
  344.         redraw_screen(maxmoves,*num,*score,nf,diamonds,mx,sx,sy,frow);
  345.     continue;
  346.     }
  347. /* M002  Added save/restore game feature.  Gregory H. Margo    */
  348. if(ch == 'S')           /* save game */
  349.     {
  350.     extern    struct    save_vars    zz;
  351.  
  352.     /* stuff away important local variables to be saved */
  353.     /* so the game state may be acurately restored    */
  354.     zz.z_x        = x;
  355.     zz.z_y        = y;
  356.     zz.z_nx        = nx;
  357.     zz.z_ny        = ny;
  358.     zz.z_sx        = sx;
  359.     zz.z_sy        = sy;
  360.     zz.z_tx        = tx;
  361.     zz.z_ty        = ty;
  362.     zz.z_lx        = lx;
  363.     zz.z_ly        = ly;
  364.     zz.z_mx        = mx;
  365.     zz.z_my        = my;
  366.     zz.z_bx        = bx;
  367.     zz.z_by        = by;
  368.     zz.z_nbx    = nbx;
  369.     zz.z_nby    = nby;
  370.     zz.z_max_score    = max_score;
  371.     zz.z_diamonds    = diamonds;
  372.     zz.z_nf        = nf;
  373.     zz.z_hd        = hd;
  374.     zz.z_vd        = vd;
  375.     zz.z_xdirection    = xdirection;
  376.     zz.z_ydirection    = ydirection;
  377.  
  378.     save_game(*num, score, bell, maxmoves, &start_of_list, tail_of_list);
  379.     /* NOTREACHED */
  380.     }
  381. if(ch == 'R')        /* restore game */
  382.     {
  383.     extern    struct    save_vars    zz;
  384.  
  385.     restore_game(num, score, bell, &maxmoves, &start_of_list, &tail_of_list);
  386.  
  387.     /* recover important local variables */
  388.     x        = zz.z_x;
  389.     y        = zz.z_y;
  390.     nx        = zz.z_nx;
  391.     ny        = zz.z_ny;
  392.     sx        = zz.z_sx;
  393.     sy        = zz.z_sy;
  394.     tx        = zz.z_tx;
  395.     ty        = zz.z_ty;
  396.     lx        = zz.z_lx;
  397.     ly        = zz.z_ly;
  398.     mx        = zz.z_mx;
  399.     my        = zz.z_my;
  400.     bx        = zz.z_bx;
  401.     by        = zz.z_by;
  402.     nbx        = zz.z_nbx;
  403.     nby        = zz.z_nby;
  404.     max_score    = zz.z_max_score;
  405.     diamonds    = zz.z_diamonds;
  406.     nf        = zz.z_nf;
  407.     hd        = zz.z_hd;
  408.     vd        = zz.z_vd;
  409.     xdirection    = zz.z_xdirection;
  410.     ydirection    = zz.z_ydirection;
  411.  
  412.     if (maxmoves == -1)
  413.         maxmoves = 0;    /* to get the "unlimited moves" message */
  414.  
  415.     goto update_game;    /* the dreaded goto    */
  416.     }
  417.  
  418. if(screen[ny][nx] == 'C')
  419.     {
  420.     screen[ny][nx] = ':';
  421.     *score+=4;
  422.     if(maxmoves != -1)
  423.         maxmoves+=250;
  424.     }
  425. switch(screen[ny][nx])
  426.     {
  427.     case '@': break;
  428.     case '*': *score+=9;
  429.     max_score -= 10;
  430.         nf++;
  431.     case ':': *score+=1;
  432.         move(3,48);
  433.         sprintf(buffer,"%d\t %d",*score,nf);
  434.         (void) addstr(buffer);
  435.     case ' ':
  436.     screen[y][x] = ' ';
  437.        screen[ny][nx] = '@';
  438.     if(!debug_disp)
  439.         {
  440.             draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
  441.             draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
  442.         }
  443.     else
  444.         {
  445.         move(y+1,x+1);
  446.         addch(' ');
  447.         move(ny+1,nx+1);
  448.         addch('@');
  449.         }
  450.     deadyet += check(&mx,&my,x,y,nx-x,ny-y,sx,sy,howdead);
  451.         move(16,0);
  452.         refresh();
  453.     y = ny;
  454.     x = nx;
  455.         break;
  456.     case 'O':
  457.     if(screen[y][nx*2-x] == 'M')
  458.         {
  459.         screen[y][nx*2-x] = ' ';
  460.         mx = my = -1;
  461.         *score+=100;
  462.             move(3,48);
  463.             sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
  464.             (void) addstr(buffer);
  465.         draw_symbol(48,10,' ');
  466.         move(16,0);
  467.             refresh();
  468.         }
  469.     if(screen[y][nx*2-x] == ' ')
  470.         {
  471.         screen[y][nx*2-x] = 'O';
  472.         screen[y][x] = ' ';
  473.             screen[ny][nx] = '@';
  474.         if(!debug_disp)
  475.         {
  476.                 draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
  477.                 draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
  478.         if(nx*2-x>sx-6&&nx*2-x<sx+6)
  479.                     draw_symbol((nx*2-x-sx+5)*3,(y-sy+3)*2,'O');
  480.         }
  481.         else
  482.         {
  483.         move(y+1,x+1);
  484.         addch(' ');
  485.         move(ny+1,nx+1);
  486.         addch('@');
  487.         move(y+1,nx*2-x+1);
  488.         addch('O');
  489.         }
  490.             deadyet += fall(&mx,&my,nx*2-x,y+1,sx,sy,howdead);
  491.             deadyet += fall(&mx,&my,x*2-nx,y,sx,sy,howdead);
  492.             deadyet += fall(&mx,&my,x,y,sx,sy,howdead);
  493.             deadyet += fall(&mx,&my,x,y-1,sx,sy,howdead);
  494.             deadyet += fall(&mx,&my,x,y+1,sx,sy,howdead);
  495.             move(16,0);
  496.             refresh();
  497.         y = ny;
  498.         x = nx;
  499.         }
  500.     break;
  501.     case '<':
  502.     case '^':
  503.     if(screen[y][nx*2-x] == ' ')
  504.         {
  505.         screen[y][nx*2-x] = '^';
  506.         screen[y][x] = ' ';
  507.             screen[ny][nx] = '@';
  508.         if(!debug_disp)
  509.         {
  510.                 draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
  511.                 draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
  512.         if(nx*2-x>sx-6&&nx*2-x<sx+6)
  513.                     draw_symbol((nx*2-x-sx+5)*3,(y-sy+3)*2,'^');
  514.         }
  515.         else
  516.         {
  517.         move(y+1,x+1);
  518.         addch(' ');
  519.         move(ny+1,nx+1);
  520.         addch('@');
  521.         move(y+1,nx*2-x+1);
  522.         addch('^');
  523.         }
  524.             deadyet += fall(&mx,&my,nx*2-x,y-1,sx,sy,howdead);
  525.             deadyet += fall(&mx,&my,x*2-nx,y,sx,sy,howdead);
  526.             deadyet += fall(&mx,&my,x,y,sx,sy,howdead);
  527.             deadyet += fall(&mx,&my,x,y+1,sx,sy,howdead);
  528.             deadyet += fall(&mx,&my,x,y-1,sx,sy,howdead);
  529.             move(16,0);
  530.             refresh();
  531.         y = ny;
  532.         x = nx;
  533.         }
  534.     break;
  535.     case '>':
  536.     if(screen[ny*2-y][x] == 'M')
  537.         {
  538.         screen[ny*2-y][x] = ' ';
  539.         mx = my = -1;
  540.         *score+=100;
  541.             move(3,48);
  542.             sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
  543.             (void) addstr(buffer);
  544.         draw_symbol(48,10,' ');
  545.         move(16,0);
  546.             refresh();
  547.         }
  548.     if(screen[ny*2-y][x] == ' ')
  549.         {
  550.         screen[ny*2-y][x] = screen[ny][nx];
  551.         screen[y][x] = ' ';
  552.             screen[ny][nx] = '@';
  553.         if(!debug_disp)
  554.         {
  555.                 draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
  556.                 draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
  557.         if(ny*2-y>sy-4&&ny*2-y<sy+4)
  558.                     draw_symbol((x-sx+5)*3,(ny*2-y-sy+3)*2,screen[ny*2-y][x]);
  559.         }
  560.         else
  561.         {
  562.         move(y+1,x+1);
  563.         addch(' ');
  564.         move(ny+1,nx+1);
  565.         addch('@');
  566.         move(ny*2-y+1,x+1);
  567.         addch(screen[ny*2-y][x]);
  568.         }
  569.             deadyet += fall(&mx,&my,x,y,sx,sy,howdead);
  570.             deadyet += fall(&mx,&my,x-1,(ny>y)?y:(y-1),sx,sy,howdead);
  571.             deadyet += fall(&mx,&my,x+1,(ny>y)?y:(y-1),sx,sy,howdead);
  572.             deadyet += fall(&mx,&my,x-1,ny*2-y,sx,sy,howdead);
  573.             deadyet += fall(&mx,&my,x+1,ny*2-y,sx,sy,howdead);
  574.             move(16,0);
  575.             refresh();
  576.         y = ny;
  577.         x = nx;
  578.         }
  579.     break;
  580.     case '!':
  581.         strcpy(howdead,"an exploding landmine");
  582.     deadyet = 1;
  583.     if(!debug_disp)
  584.         {
  585.             draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
  586.             draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
  587.         }
  588.     else
  589.         {
  590.         move(y+1,x+1);
  591.         addch(' ');
  592.         move(ny+1,nx+1);
  593.         addch('@');
  594.         }
  595.         move(16,0);
  596.     refresh();
  597.         break;
  598.     case 'X':
  599.     if(nf == diamonds)
  600.         {
  601.         *score+=250;
  602.         showpass(*num);
  603.         return NULL;
  604.         }
  605.     break;
  606.     case 'T':
  607.     if(tx > -1)
  608.         {
  609.         screen[ny][nx] = ' ';
  610.         screen[y][x] = ' ';
  611.         lx = x;
  612.         ly = y;
  613.         y = ty;
  614.         x = tx;
  615.         screen[y][x] = '@';
  616.         sx = x;
  617.         sy = y;
  618.         *score += 20;
  619.             move(3,48);
  620.             sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
  621.             (void) addstr(buffer);
  622.         if(!debug_disp)
  623.             display(sx,sy,frow,*score);
  624.         else
  625.         map(frow);
  626.         deadyet = fall(&mx,&my,nx,ny,sx,sy,howdead);
  627.         if(deadyet == 0)
  628.         deadyet = fall(&mx,&my,lx,ly,sx,sy,howdead);
  629.         if(deadyet == 0)
  630.         deadyet = fall(&mx,&my,lx+1,ly-1,sx,sy,howdead);
  631.         if(deadyet == 0)
  632.         deadyet = fall(&mx,&my,lx+1,ly+1,sx,sy,howdead);
  633.         if(deadyet == 0)
  634.         deadyet = fall(&mx,&my,lx-1,ly+1,sx,sy,howdead);
  635.         if(deadyet == 0)
  636.         deadyet = fall(&mx,&my,lx-1,ly-1,sx,sy,howdead);
  637.         move(16,0);
  638.         refresh();
  639.         }
  640.     else
  641.         {
  642.         screen[ny][nx] = ' ';
  643.         printf("Teleport out of order");
  644.         }
  645.     break;
  646.     case 'M':
  647.     strcpy(howdead,"a hungry monster");
  648.     deadyet = 1;
  649.     if(!debug_disp)
  650.             draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
  651.     else
  652.         {
  653.         move(y+1,x+1);
  654.         addch(' ');
  655.         }
  656.         move(16,0);
  657.     refresh();
  658.         break;
  659.     case 'S':
  660.     strcpy(howdead,"walking into a monster");
  661.     deadyet = 1;
  662.     if(!debug_disp)
  663.             draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
  664.     else
  665.         {
  666.         move(y+1,x+1);
  667.         addch(' ');
  668.         }
  669.         move(16,0);
  670.     refresh();
  671.         break;
  672.     default:
  673.         break;
  674.     }
  675. if((y == ny) && (x == nx) && (maxmoves>0))
  676.     {
  677.     (void) sprintf(buffer,"Moves remaining = %d ",--maxmoves);
  678.     move(15,48);
  679.     (void) addstr(buffer);
  680.     }
  681. if(maxmoves == 0)
  682.     {
  683.     strcpy(howdead,"running out of time");
  684.     return(howdead);
  685.     }
  686. if(!debug_disp)
  687.     {
  688.     if ((x<(sx-3))&& (deadyet ==0))         /* screen scrolling if necessary */
  689.         {
  690.         sx-=6;
  691.         if(sx < 4)
  692.         sx = 4;
  693.         display(sx,sy,frow,*score);
  694.         }
  695.     if ((y<(sy-2))&& (deadyet == 0))
  696.         {
  697.         sy-=5;
  698.         if(sy < 2)
  699.         sy = 2;
  700.         display(sx,sy,frow,*score);
  701.         }
  702.     if ((x>(sx+3)) && (deadyet == 0))
  703.         {
  704.         sx+=6;
  705.         if(sx>(ROWLEN -5))
  706.         sx = ROWLEN -5;
  707.         display(sx,sy,frow,*score);
  708.         }
  709.     if ((y>(sy+2))&& (deadyet ==0))
  710.         {
  711.         sy+=5;
  712.         if(sy > (NOOFROWS-3))
  713.         sy = NOOFROWS -3;
  714.         display(sx,sy,frow,*score);
  715.         }
  716.     }
  717.  
  718.     /* MONSTER SECTION  */
  719.  
  720. /* big monster first */
  721. if(mx == -2)                              /* has the monster been killed ? */
  722.     {
  723.     *score+=100;
  724.     mx = my = -1;
  725.     move(3,48);
  726.     sprintf(buffer,"%d\t %d\t",*score,nf);
  727.     (void) addstr(buffer);
  728.     draw_symbol(48,10,' ');
  729.     move(16,0);
  730.     refresh();
  731.     }                                     /* if monster still alive */
  732. if(mx != -1)                              /* then move that monster ! */
  733.     {
  734.     screen[my][mx] = ' ';
  735.     if(mx>x)
  736.         xdirection = -1;
  737.     else
  738.         xdirection = 1;
  739.     if(!debug_disp)
  740.     {
  741.         if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6)))
  742.             draw_symbol((mx-sx+5)*3,(my-sy+3)*2,' ');
  743.     }
  744.     else
  745.     {
  746.     move(my+1,mx+1);
  747.     addch(' ');
  748.     }
  749.     if((hd = (mx-x))<0)
  750.     hd = -hd;
  751.     if((vd = (my-y))<0)
  752.     vd = -vd;
  753.     if((hd>vd)&&((screen[my][mx+xdirection] == ' ')||(screen[my][mx+xdirection] == '@')))
  754.     mx+=xdirection;
  755.     else
  756.         {
  757.         if(my>y)
  758.             ydirection = -1;
  759.     else
  760.             ydirection = 1;
  761.         if((screen[my+ydirection][mx] == ' ')||(screen[my+ydirection][mx] == '@'))
  762.         my+=ydirection;
  763.     else
  764.             if((screen[my][mx+xdirection] == ' ')||(screen[my][mx+xdirection] == '@'))
  765.     mx+=xdirection;
  766.     }
  767.     if(!debug_disp)
  768.     {
  769.         if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6)))
  770.             draw_symbol((mx-sx+5)*3,(my-sy+3)*2,'M');
  771.     }
  772.     else
  773.     {
  774.     move(my+1,mx+1);
  775.     addch('M');
  776.     }
  777.     if(screen[my][mx] == '@')                     /* ha! gottim! */
  778.     {
  779.     strcpy(howdead,"a hungry monster");
  780.         move(16,0);
  781.     refresh();
  782.         return(howdead);
  783.     }
  784.     screen[my][mx] = 'M';
  785.     move(16,0);
  786.     refresh();
  787.     }
  788.  
  789. current = &start_of_list;                         /* baby monsters now */
  790. while((current != tail_of_list)&&(!deadyet))
  791.     /* deal with those little monsters */
  792.     {
  793.     monster = current->next;
  794.     new_disp = new_direction( monster->x, monster->y, monster->mx, monster->my );
  795.     if(monster->under!='S')             /* if on top of another baby */
  796.     {
  797.         screen[monster->y][monster->x] = monster->under;
  798.         if(!debug_disp)
  799.         {
  800.             if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)))
  801.                 draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,monster->under);
  802.         }
  803.         else
  804.         {
  805.             move(monster->y+1,monster->x+1);
  806.             addch(monster->under);
  807.         }
  808.         if(monster->under == ' ')
  809.          deadyet+=check(&mx,&my,monster->x,monster->y,new_disp.d[0],new_disp.d[1],sx,sy,howdead);
  810.     }
  811.     else
  812.     monster->under=' ';
  813.     monster->mx = new_disp.d[0];
  814.     monster->my = new_disp.d[1];
  815.     monster->x += monster->mx;
  816.     monster->y += monster->my;
  817.     monster->under = screen[monster->y][monster->x];
  818.     screen[monster->y][monster->x] = 'S';        /* move into new space */
  819.     if(!debug_disp)
  820.     {
  821.         if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)))
  822.             draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,'S');
  823.     }
  824.     else
  825.     {
  826.     move(monster->y+1,monster->x+1);
  827.     addch('S');
  828.     }
  829.     if(monster->under == '@')                     /* monster hit you? */
  830.         {
  831.     strcpy(howdead,"the little monsters");
  832.     move(16,0);
  833.     refresh();
  834.         return(howdead);
  835.         }
  836.     if(monster->under == '+')                    /* monster hit cage? */
  837.         {
  838.     *score +=20;
  839.     max_score -= 20;
  840.         move(3,48);
  841.         sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
  842.         (void) addstr(buffer);
  843.         /* remove from chain, and insert at the end (at last_of_list) */
  844.     if(monster == tail_of_list)
  845.         tail_of_list = tail_of_list->prev;
  846.     else
  847.         {
  848.           current->next = monster-> next;
  849.         current->next->prev = current;
  850.         monster->next = NULL;
  851.         monster->prev = last_of_list;
  852.         last_of_list->next = monster;
  853.         last_of_list = monster;
  854.         }
  855.     screen[monster->y][monster->x] = '*';
  856.     if(!debug_disp)
  857.         {
  858.             if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)))
  859.                     draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,'*');
  860.         }
  861.     else
  862.         {
  863.         move(monster->y+1,monster->x+1);
  864.         addch('*');
  865.         }
  866.         }
  867.     else
  868.     current = monster;
  869.     move(16,0);
  870.     refresh();
  871.     }
  872.  
  873. if((edit_mode)&&(deadyet)) {         /* stop death if testing */
  874.     if(!debug_disp)
  875.     move(18,0);
  876.     else
  877.     move(20,0);
  878.     addstr("You were killed by ");
  879.     addstr(howdead);
  880.     addstr("\nPress 'c' to continue.");
  881.     refresh();
  882.     ch=getch();
  883.     if(ch == 'c')
  884.     deadyet = 0;
  885.     if(!debug_disp)
  886.     move(18,0);
  887.      else
  888.     move(20,0);
  889.     addstr("                                                              ");
  890.     addstr("\n                      ");
  891.     refresh();
  892.     }
  893.  
  894. }
  895. return(howdead);
  896. }
  897.