home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / gamearca / pc_xbd.arj / FIELD.C < prev    next >
C/C++ Source or Header  |  1990-11-28  |  15KB  |  631 lines

  1. /*********************************************/
  2. /* you just keep on pushing my luck over the */
  3. /*           BOULDER        DASH             */
  4. /*                                           */
  5. /*     Jeroen Houttuin, ETH Zurich, 1990     */
  6. /*                                           */
  7. /*                                           */
  8. /*      PC-VGA version from :                */
  9. /*                                           */
  10. /*        Herve SOULARD, Paris, 1990        */
  11. /*                                           */
  12. /*********************************************/
  13.  
  14. #include <stdio.h>
  15. #include <signal.h>
  16. #include <time.h>
  17. #include <sys/timeb.h>
  18. #include "xbd.h"
  19.  
  20. void blink(i, j)
  21. int    i, j;
  22. {
  23.     field[i][j].changed = TRUE;
  24. }
  25.  
  26.  
  27. void move_cell(i, j, ii, jj)
  28. int    i, j, ii, jj;
  29. {
  30.     field[ii][jj] = field[i][j];
  31.     field[ii][jj].speed = 1;
  32.     field[ii][jj].changed = TRUE;
  33.     field[ii][jj].dir = ((ii - i) == 1) ? S : ((i - ii) == 1) ? 
  34.                                          N : ((jj - j) == 1) ? E : W;
  35.     set_cell(i, j, SPACE);
  36. }
  37.  
  38.  
  39. void    explode(a, b, stage)
  40. int    a, b, stage;
  41. {
  42.   if (field[a][b].content != STEEL) {
  43.       set_cell(a, b, EXPLOSION);
  44.       field[a][b].stage = stage;/* dirty fix, not what stage was meant for */
  45.   }
  46. }
  47.  
  48.  
  49. Bool move_nucbal(i, j, t)
  50. int    i, j, t;
  51. {
  52.     ii = (!t) ? (i + y - 1) % y : i;
  53.     if (!t)
  54.         jj = j;
  55.     else
  56.         switch (field[i][j].dir) {
  57.             case E:
  58.                 jj = (t == 1) ? (j + x - 1) % x : (j + 1) % x;
  59.                 break;
  60.             case W:
  61.             default:
  62.                 jj = (t == 2) ? (j + x - 1) % x : (j + 1) % x;
  63.                 break;
  64.         }
  65.     switch (field[ii][jj].content) {
  66.         case SPACE:
  67.             move_cell(i, j, ii, jj);
  68.             return (TRUE);
  69.         case NUCBAL:
  70.             explode(i, j, DIAEXPLO);
  71.             explode(ii, jj, DIAEXPLO);
  72.             return (TRUE);
  73.         default:
  74.             if (field[i][j].dir == N)
  75.                 field[i][j].dir = E;
  76.             else
  77.                 field[i][j].dir = ((field[i][j].dir + 2) % 4);
  78.             return (FALSE);
  79.     }
  80. }
  81.  
  82.  
  83. Bool move_monster(content, direction)
  84. char    content, direction;
  85. {
  86.     switch (direction) {
  87.         case N:    
  88.             ii = (i + y - 1) % y;
  89.             jj    = j;
  90.             break;
  91.         case E:
  92.             jj = (j + 1) % x;
  93.             ii = i;
  94.             break;
  95.         case S:
  96.             ii = (i + 1) % y;
  97.             jj = j;
  98.             break;
  99.         default:
  100.             jj = (j + x - 1) % x;
  101.             ii = i;
  102.             break;            /* default must be SOMEthing, West */
  103.     }
  104.     switch (field[ii][jj].content) {
  105.         case SPACE:
  106.             if (!field[ii][jj].changed) {
  107.                 move_cell(i, j, ii, jj);
  108.                 field[ii][jj].dir = direction;
  109.                 return (TRUE);
  110.             } 
  111.             else
  112.                 return (FALSE);
  113.             break;
  114.         case BOULDER:
  115.         case DIAMOND:
  116.             if ((direction == N) && (field[ii][jj].speed != 0))
  117.                 if (content == RMONSTER) {
  118.                     explode(i, j, DIAEXPLO);
  119.                     return (TRUE);
  120.                 } 
  121.                 else 
  122.                     if (content == LMONSTER) {
  123.                         explode(i, j, SPACEEXPLO);
  124.                         return (TRUE);
  125.                     } 
  126.                     else
  127.                         return (FALSE);
  128.             else
  129.                 return (FALSE);
  130.             break;
  131.         default:
  132.             return (FALSE);
  133.             break;
  134.     }
  135.     return (FALSE);
  136. }
  137.  
  138.  
  139. Bool search_destroy(content)
  140. char    content;
  141. {
  142.     ii = (i + y - 1) % y;
  143.     jj = (j + x - 1) % x;
  144.     if (field[i][jj].content == PLAYER || field[i][jj].content == BLOB) {
  145.         set_cell(i, j, SPACE);
  146.         if (field[i][jj].content == PLAYER) {
  147.             lives--;
  148.             scoreobs = TRUE;
  149.         }
  150.         if (content == RMONSTER)
  151.             explode(i, jj, DIAEXPLO);
  152.         else
  153.             explode(i, jj, SPACEEXPLO);
  154.         return (TRUE);
  155.     } 
  156.     else 
  157.         if (field[ii][j].content == PLAYER || field[ii][j].content == BLOB) {
  158.             set_cell(i, j, SPACE);
  159.             if (field[ii][j].content == PLAYER) {
  160.                 lives--;
  161.                 scoreobs = TRUE;
  162.             }
  163.             if (content == RMONSTER)
  164.                 explode(ii, j, DIAEXPLO);
  165.             else
  166.                 explode(ii, j, SPACEEXPLO);
  167.             return (TRUE);
  168.         }
  169.         else {
  170.             ii = (i + 1) % y;
  171.             jj = (j + 1) % x;
  172.             if (field[i][jj].content == PLAYER || field[i][jj].content == BLOB) {
  173.                 set_cell(i, j, SPACE);
  174.                 if (field[i][jj].content == PLAYER) {
  175.                     lives--;
  176.                     scoreobs = TRUE;
  177.                 }
  178.                 if (content == RMONSTER)
  179.                     explode(i, jj, DIAEXPLO);
  180.                 else
  181.                     explode(i, jj, SPACEEXPLO);
  182.                 return (TRUE);
  183.             } 
  184.             else 
  185.                 if (field[ii][j].content == PLAYER || field[ii][j].content == BLOB) {
  186.                     set_cell(i, j, SPACE);
  187.                     if (field[ii][j].content == PLAYER) {
  188.                         lives--;
  189.                         scoreobs = TRUE;
  190.                     }
  191.                     if (content == RMONSTER)
  192.                         explode(ii, j, DIAEXPLO);
  193.                     else
  194.                         explode(ii, j, SPACEEXPLO);
  195.                     return (TRUE);
  196.                 } 
  197.                 else
  198.                     return (FALSE);
  199.             }
  200.     }
  201.  
  202. void propagate(i, j, dias)
  203. int             i, j;
  204. Bool            dias;
  205. {
  206.     int    t, it, jt;
  207.     if (dias)
  208.         set_cell(i, j, DIAMOND);
  209.     else {
  210.         field[i][j].checked = PROPAGATED;
  211.         field[i][j].caught = TRUE;
  212.     }
  213.     for (t = 0; (t < 4); ++t) {
  214.         it = (t == 1) ? (i + y - 1) % y : (t == 3) ? (i + 1) % y : i;
  215.         jt = (t == 2) ? (j + x - 1) % x : (t == 0) ? (j + 1) % x : j;    
  216.         switch (field[it][jt].content) {
  217.             case BLOB:
  218.                 if (field[it][jt].checked != PROPAGATED)
  219.                     propagate(it, jt, dias);
  220.                 break;
  221.             case SPACE:
  222.             case GRASS:
  223.                 if (!(rand() % (blobbreak + 1))) {
  224.                     set_cell(it, jt, BLOB);
  225.                     field[it][jt].checked = PROPAGATED;
  226.                     field[it][jt].caught = TRUE;
  227.                 }
  228.                 break;
  229.             default:
  230.                 break;
  231.         }
  232.     }    
  233. }
  234.  
  235.  
  236. Bool caught(i, j)
  237. int    i, j;
  238. {
  239.     Bool    Free;
  240.     int    t, it, jt;
  241.  
  242.     field[i][j].checked = 1;
  243.     Free = FALSE;
  244.  
  245.     for (t = 0; ((t < 4) && !Free); ++t) {
  246.         it = (t == 1) ? (i + y - 1) % y : (t == 3) ? (i + 1) % y : i;
  247.         jt = (t == 2) ? (j + x - 1) % x : (t == 0) ? (j + 1) % x : j;
  248.         
  249.         switch (field[it][jt].content) {
  250.             case SPACE:
  251.             case GRASS:
  252.             case RMONSTER:
  253.             case LMONSTER:
  254.             case EATER:
  255.                 Free = TRUE;
  256.                 break;
  257.             case BLOB:
  258.                 Free = (Free || ((field[it][jt].checked == 1) ? 
  259.                                  !field[i][j].caught : !caught(it, jt)));
  260.                 break;
  261.             default:
  262.                 break;
  263.         }
  264.     }
  265.     field[i][j].caught != Free;
  266.     return (!Free);
  267. }
  268.  
  269.  
  270. void diaboulderproc(i, j)
  271. int    i, j;
  272. {
  273.     
  274.     if (field[i][j].content == DIAMOND)
  275.         blink(i, j);
  276.     
  277.     ii = (ii + 1) % y;
  278.     field[i][j].dir = NODIR;
  279.     switch (field[ii][j].content) {
  280.         case SPACE:            /* directly underneath */
  281.             move_cell(i, j, ii, j);
  282.             field[ii][j].speed = 1;
  283.             break;
  284.         case PLAYER:
  285.             if (field[i][j].speed) {
  286.                 set_cell(i, j, SPACE);
  287.                 explode(ii, j, SPACEEXPLO);
  288.                 lives--;
  289.                 scoreobs = TRUE;
  290.             }
  291.             break;
  292.         case LMONSTER:
  293.         case EATER:
  294.             if (field[i][j].speed) {
  295.                 set_cell(i, j, SPACE);
  296.                 explode(ii, j, SPACEEXPLO);
  297.             }
  298.             break;
  299.         case RMONSTER:
  300.             if (field[i][j].speed) {
  301.                 set_cell(i, j, SPACE);
  302.                 explode(ii, j, DIAEXPLO);
  303.             }
  304.             break;
  305.         case TINKLE:
  306.             if (field[i][j].speed) {
  307.                 tinkact = TRUE;
  308.                 field[ii][j].stage = field[i][j].content;
  309.                 field[ii][j].speed = 1;
  310.                 set_cell(i, j, SPACE);
  311.                 break;
  312.             }
  313.             break;
  314.         case WALL:
  315.         case BOULDER:
  316.         case DIAMOND:
  317.         case EXPLOSION:
  318.             jj = (j + 1) % x;
  319.             if (field[i][jj].content == SPACE && field[ii][jj].content == SPACE) {
  320.                 move_cell(i, j, i, jj);
  321.                 field[i][jj].speed = 0;
  322.             } 
  323.             else {
  324.                 jj = (j - 1) % x;
  325.                 if (field[i][jj].content == SPACE && field[ii][jj].content == SPACE) {
  326.                     move_cell(i, j, i, jj);
  327.                     field[i][jj].speed = 0;
  328.                 }
  329.                 else
  330.                     field[i][j].speed = 0;
  331.             }
  332.             break;
  333.         default:
  334.             field[i][j].speed = 0;
  335.             break;
  336.     }
  337. }
  338.  
  339.  
  340. void calculate_field()
  341. {
  342.     players = 0;
  343.  
  344.     /* Iterate through each horizontal line */
  345.     if (!curtime)
  346.         curorder = KILL;
  347.     for (i = y - 1; i >= 0; --i) {
  348.         for (j = 0; j < x; ++j) {
  349.             if (!(field[i][j].changed)) {
  350.                 ii = i;
  351.                 jj = j;
  352.                 switch (field[i][j].content) {
  353.                     case PLAYER:
  354.                         players++;
  355.                         switch (curorder) {
  356.                             case STAND:
  357.                                 break;
  358.                             case UP:
  359.                                 ii = (i + y - 1) % y;
  360.                                 break;
  361.                             case DOWN:
  362.                                 ii = (i + 1) % y;
  363.                                 break;
  364.                             case LEFT:
  365.                                 jj = (j + x - 1) % x;
  366.                                 break;
  367.                             case RIGHT:
  368.                                 jj = (j + 1) % x;
  369.                                 break;
  370.                         }
  371.                         if (!(curorder == STAND) && !(field[i][j].changed)) {
  372.                             if (curorder == KILL) {
  373.                                 set_cell(i, j, EXPLOSION);
  374.                                 lives--;
  375.                                 scoreobs = TRUE;
  376.                                 break;
  377.                             }
  378.                             switch (field[ii][jj].content) {
  379.                                 case SPACE:
  380.                                 case GRASS:
  381.                                 case DIAMOND:
  382.                                     if (field[ii][jj].content == DIAMOND) {
  383.                                         if (curorder == UP && field[ii][jj].speed)
  384.                                             break;
  385.                                         score += diapoints;
  386.                                         if (diareq)
  387.                                             diareq--;
  388.                                         scoreobs = TRUE;
  389.                                     }
  390.                                     if (steal)
  391.                                         set_cell(ii, jj, SPACE);
  392.                                     else
  393.                                         move_cell(i, j, ii, jj);
  394.                                     break;
  395.                                 case BOULDER:
  396.                                     jjj = (2 * jj - j + x) % x;
  397.                                     if (field[i][jjj].content == SPACE && 
  398.                                         ((rand() % 2) == 0) &&    
  399.                                         !(field[ii][jj].dir == E))    {
  400.                                         move_cell(i, jj, i, jjj);
  401.                                         field[i][jjj].speed = 0;
  402.                                         if (!steal) {
  403.                                             move_cell(i, j, i, jj);
  404.                                         }
  405.                                     }
  406.                                     break;
  407.                                 case EXIT:
  408.                                     if (diareq < 1) {
  409.                                         if (!steal)
  410.                                             move_cell(i, j, ii, jj);
  411.                                         else
  412.                                             set_cell(ii, jj, SPACE);
  413.                                         if (!levincreased) {
  414.                                             levelnum++;
  415.                                             lives++;
  416.                                             levincreased = TRUE;
  417.                                             for (jj = curtime / 10; jj > 0; --jj) {
  418.                                                 score += 10;
  419.                                                 draw_score();
  420.                                             }
  421.                                         }
  422.                                         gamestop = TRUE;
  423.                                         stoplevel = TRUE;
  424.                                     }
  425.                                     break;
  426.                             }
  427.                         }
  428.                         blink(i, j);
  429.                         break;
  430.                     case DIAMOND:
  431.                     case BOULDER:
  432.                         diaboulderproc(i, j);
  433.                         break;
  434.                     case EATER:
  435.                         if (!field[i][j].speed) {
  436.                             for (jjj = 0; ((!field[i][j].changed) && (jjj < 4)); ++jjj) {
  437.                                 ii = (jjj == 2) ? (i + 1) % y : (jjj == 0) ? (i + y - 1) % y : i;
  438.                                 jj = (jjj == 1) ? (j + 1) % x : (jjj == 3) ? (j + x - 1) % x : j;
  439.                                 switch (field[ii][jj].content) {
  440.                                     case PLAYER:
  441.                                         lives--;
  442.                                         scoreobs = TRUE;
  443.                                     case DIAMOND:
  444.                                         if (field[ii][jj].speed && (ii == i - 1) && (jj == j))
  445.                                             break;
  446.                                     case BLOB:
  447.                                     case LMONSTER:
  448.                                     case RMONSTER:
  449.                                     case NUCBAL:
  450.                                         move_cell(i, j, ii, jj);
  451.                                         break;
  452.                                     default:
  453.                                         break;
  454.                                 }
  455.                             }
  456.                         }
  457.                         else {
  458.                             jjj = field[i][j].dir;
  459.                             ii = (jjj == 2) ? (i + 1) % y : (jjj == 0) ? (i + y - 1) % y : i;
  460.                             jj = (jjj == 1) ? (j + 1) % x : (jjj == 3) ? (j + x - 1) % x : j;
  461.                             switch (field[ii][jj].content) {
  462.                                 case LMONSTER:
  463.                                 case BLOB:
  464.                                 case SPACE:
  465.                                 case GRASS:
  466.                                 case DIAMOND:
  467.                                 case RMONSTER:
  468.                                 case PLAYER:
  469.                                 case NUCBAL:
  470.                                     if (field[ii][jj].content == PLAYER) {
  471.                                         lives--;
  472.                                         scoreobs = TRUE;
  473.                                     }
  474.                                     move_cell(i, j, ii, jj);
  475.                                     break;
  476.                                 case BOULDER:
  477.                                     jjj = (2 * jj - j + x) % x;
  478.                                     if (field[i][jjj].content == SPACE && 
  479.                                          ((rand() % 2) == 0) && 
  480.                                          !(field[ii][jj].dir == E)) {
  481.                                          move_cell(i, jj, i, jjj);
  482.                                          move_cell(i, j, i, jj);
  483.                                      }
  484.                                      else
  485.                                          field[i][j].speed = 0;
  486.                                      break;
  487.                                 default:
  488.                                     field[i][j].speed = 0;
  489.                                     break;
  490.                             }
  491.                         }
  492.                         blink(i, j);
  493.                         break;
  494.                     case RMONSTER:
  495.                         blink(i, j);
  496.                         if (search_destroy(RMONSTER))
  497.                             break;
  498.                         jjj =    3;
  499.                         while (jjj >= 0 && !move_monster(RMONSTER, (field[i][j].dir + jjj + 2) % 4))
  500.                             jjj--;
  501.                         break;
  502.                     case LMONSTER:
  503.                         blink(i, j);
  504.                         if (search_destroy(LMONSTER))
  505.                             break;
  506.                         jjj = 0;
  507.                         while (jjj <= 4 && !move_monster(LMONSTER, (field[i][j].dir + jjj + 3) % 4))
  508.                             jjj++;
  509.                         break;
  510.                     case EXPLOSION:
  511.                         jjj = field[i][j].stage;
  512.                         if (!(jjj % 5)) {
  513.                             jjj++;        /* use jjj for setting new stage */
  514.                             ii = (i + 1) % y;
  515.                             jj = (j + 1) % x;
  516.                             explode(i, j, jjj);
  517.                             explode(i, jj, jjj);
  518.                             explode(ii, j, jjj);
  519.                             explode(ii, jj, jjj);
  520.                             ii = (i + y - 1) % y;
  521.                             explode(ii, j, jjj);
  522.                             explode(ii, jj, jjj);
  523.                             jj = (j + x - 1) % x;
  524.                             explode(ii, jj, jjj);
  525.                             explode(i, jj, jjj);
  526.                             ii = (i + 1) % y;
  527.                             explode(ii, jj, jjj);
  528.                         }
  529.                         else {
  530.                             if (jjj % 10 < 3)
  531.                                 field[i][j].stage++;
  532.                             else 
  533.                                 if (jjj > DIAEXPLO) {
  534.                                     set_cell(i, j, DIAMOND);
  535.                                 } 
  536.                                 else 
  537.                                     if (jjj > BOULDEXPLO) {
  538.                                         set_cell(i, j, BOULDER);
  539.                                     }
  540.                                     else
  541.                                         if (jjj > SPACEEXPLO) {
  542.                                             set_cell(i, j, SPACE);
  543.                                         }
  544.                                         else
  545.                                             field[i][j].stage++;
  546.                         }
  547.                         break;
  548.                     case EXIT:
  549.                         blink(i, j);
  550.                         break;
  551.                     case BLOB:
  552.                         blobcells++;
  553.                         if (blobcollapse)
  554.                             set_cell(i, j, BOULDER);
  555.                         else {
  556.                             if (blobcells > critical)
  557.                                 blobcollapse = TRUE;
  558.                             else {
  559.                                 if (!field[i][j].checked) {
  560.                                     if (caught(i, j))
  561.                                         propagate(i, j, DIAMOND);
  562.                                     else
  563.                                         propagate(i, j, FALSE);
  564.                                 }
  565.                                 field[i][j].checked = FALSE;
  566.                                 field[i][j].caught = TRUE;
  567.                             }
  568.                         }
  569.                         blink(i, j);
  570.                         break;
  571.                     case NUCBAL:
  572.                         for (jjj = 0; ((jjj < 3) && !move_nucbal(i, j, jjj)); ++jjj);
  573.                         blink(i, j);
  574.                         break;
  575.                     case MAGICWALL:
  576.                         jj = (j + x - 1) % x;
  577.                         if (field[i][jj].content == SPACE)
  578.                             set_cell(i, jj, MAGICWALL);
  579.                         jj = (j + 1) % x;
  580.                         if (field[i][jj].content == SPACE)
  581.                             set_cell(i, jj, MAGICWALL);
  582.                         break;
  583.                     case TINKLE:
  584.                         if (tinkact) {
  585.                             blink(i, j);
  586.                             if (tinkdur > 0) {
  587.                                 switch (field[i][j].stage) {
  588.                                     case BOULDER:
  589.                                         {
  590.                                             field[i][j].content = DIAMOND;
  591.                                             diaboulderproc(i, j);
  592.                                             break;
  593.                                         }
  594.                                     case DIAMOND:
  595.                                         {
  596.                                             field[i][j].content = BOULDER;
  597.                                             diaboulderproc(i, j);
  598.                                             break;
  599.                                         }
  600.                                     default:
  601.                                         break;
  602.                                 }
  603.                             }
  604.                         }
  605.                         set_cell(i, j, TINKLE);    /* reset to empty tinkle wall */
  606.                         break;
  607.                     default:
  608.                         break;
  609.                 }
  610.             }
  611.         }
  612.     }
  613.     curorder = STAND;        /* reset orders */
  614.     blobcells = 0;
  615.     pgc = (pgc == pgc1) ? ((rand() % 22) == 0) ? pgc2 : pgc1 : pgc1;
  616.     dgc = (dgc == dgc1) ? dgc2 : dgc1;
  617.     lgc = (lgc == lgc1) ? lgc2 : lgc1;
  618.     rgc = (rgc == rgc1) ? rgc2 : rgc1;
  619.     egc = (egc == egc1) ? egc2 : egc1;
  620.     Bgc = (Bgc == Bgc1) ? Bgc2 : Bgc1;
  621.     if (tinkact)
  622.         tgc = (tgc == tgc1) ? tgc2 : tgc1;
  623.     if (!diareq) {
  624.         Egc = (Egc == Egc1) ? Egc2 : Egc1;
  625.     if (diareq == 0) {
  626.         diapoints = extradiapoints;
  627.         scoreobs = TRUE;
  628.     }
  629. }
  630. }
  631.