home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / games / volume13 / x4war2 / part01 / war.c < prev    next >
C/C++ Source or Header  |  1992-08-03  |  22KB  |  957 lines

  1. #include "war.h"
  2.  
  3. extern Arr arr[4][6][5], mid[3][3];
  4.  
  5. extern Sapper_path sap[];
  6.  
  7. extern int round;
  8.  
  9. /*******************************************************************
  10. *
  11. *   Synopsis
  12. *    fatal_error(s)
  13. *        char *s;
  14. *
  15. *   Description
  16. *    it prints s as an error message and exit.
  17. *
  18. *******************************************************************/
  19.  
  20. fatal_error(s)
  21. char *s;
  22. {
  23.     printf("%s\n", s);
  24.     exit(-1);
  25. }
  26.  
  27.  
  28.  
  29. /****************************************************************
  30. *
  31. *   Synopsis
  32. *    syntax(s)
  33. *        char *s;
  34. *
  35. *   Argument
  36. *    s    the program name, usually x4war;
  37. *
  38. *   Description
  39. *    x4war command line arguments specification
  40. *
  41. ****************************************************************/
  42.  
  43. syntax(s)
  44. char *s;
  45. {
  46.     printf("Usage: %s [options ...]\n\n", s);
  47.     printf("where options include:\n");
  48.     printf("\t-p0 string\t\tplayer0's name\n");
  49.     printf("\t-d0 string\t\tplayer0's display\n");
  50.     printf("\t-c0 string\t\tplayer0's node color\n");
  51.     printf("\t-p1 string\t\tplayer1's name\n");
  52.     printf("\t-d1 string\t\tplayer1's display\n");
  53.     printf("\t-c1 string\t\tplayer1's node color\n");
  54.     printf("\t-p2 string\t\tplayer2's name\n");
  55.     printf("\t-d2 string\t\tplayer2's display\n");
  56.     printf("\t-c2 string\t\tplayer2's node color\n");
  57.     printf("\t-p3 string\t\tplayer3's name\n");
  58.     printf("\t-d3 string\t\tplayer3's display\n");
  59.     printf("\t-c3 string\t\tplayer3's node color\n");
  60.     printf("\t-two \t\t\tplay a two players game\n");
  61.     printf("\t-debug\t\t\ta default deploy\n");
  62.     printf("\t-usage\t\t\tthis usage list\n");
  63.     printf("\t-help\t\t\tthis usage list\n\n");
  64. }
  65.  
  66.  
  67.  
  68. /***********************************************************************
  69.  *
  70.  *  Synopsis
  71.  *    int fight(x, y)
  72.  *        int x, y;
  73.  *
  74.  *  Arguments
  75.  *    x, y    representing two node values between COLOURS and BOMB.
  76.  *        x must be a movable, i.e., not COLOURS and MINE.
  77.  *
  78.  *  Return values
  79.  *    x < y: return 2;
  80.  *    x = y: return 3;
  81.  *    x > y: return 4;
  82.  *
  83.  *  Description
  84.  *    it returns the fighting result when node x moved to meet node y.
  85.  *
  86.  ***********************************************************************/
  87.  
  88. int fight(x, y)
  89. int x, y;
  90. {
  91.     if (x==SAPPER && y==MINE)  return(4);
  92.     if (x==BOMB || y==BOMB)  return(3);
  93.     if (x==y) return(3);
  94.     if (x<y)  return(2);
  95.     if (x>y)  return(4);
  96. }
  97.  
  98.  
  99. /**********************************************************************
  100. *
  101. *   Synopsis
  102. *    int boardtofield(x, y, i, j)
  103. *        int x, y;
  104. *        int *i, *j;        return values
  105. *
  106. *   Arguments
  107. *    x, y    coordinates of a point on board;
  108. *    *i, *j  contain the converted field coordinates;
  109. *
  110. *   Return values
  111. *    return a value from F0 to OTHERPLACE according to the position (x,y),
  112. *    i and j are set if returned values between F0 and RIP.
  113. *
  114. ***********************************************************************/
  115.  
  116. int boardtofield(x, y, i, j)
  117. int x, y, *i, *j;
  118. {
  119.     if (x>=315 && x<=555 && y>=565 && y<=855) {
  120.     *j = (x-310)/50;
  121.     *i = (y-560)/50;
  122.     return(F0);
  123.     }
  124.     if (x>=565 && x<=855 && y>=315 && y<=555) {
  125.     *i = (x-560)/50;
  126.     *j = 4-(y-310)/50;
  127.     return(F1);
  128.     }
  129.     if (x>=315 && x<=555 && y>=15 && y<=305) {
  130.     *i = 5-(y-10)/50;
  131.     *j = 4-(x-310)/50;
  132.     return(F2);
  133.     }
  134.     if (x>=15 && x<=305 && y>=315 && y<=555) {
  135.     *i = 5-(x-10)/50;
  136.     *j = (y-310)/50;
  137.     return(F3);
  138.     }
  139.     if (x>=315 && x<=555 && y>=315 && y<=555) {
  140.     *j = (x-310)/100;
  141.     *i = (y-310)/100;
  142.     return(MIDFIELD);
  143.     }
  144.     if (x>=35 && x<=285 && y>=585 && y<=835) {
  145.     *j = (x-35)/50;
  146.     *i = (y-585)/50;
  147.     return(RIP);
  148.     }
  149.  
  150.     if (x>=BUTTON_X && x<=BUTTON_X + BUTTON_WIDTH) {
  151.     if (y>=610 && y<=635)  return(NEW);
  152.     if (y>=650 && y<=675)  return(READY);
  153.     if (y>=690 && y<=715)  return(REDEPLOY);
  154.     if (y>=730 && y<=755)  return(PEACE);
  155.     if (y>=770 && y<=795)  return(SURRENDER);
  156.     if (y>=810 && y<=835)  return(QUIT);
  157.     }
  158.     return(OTHERPLACE);
  159. }
  160.  
  161.  
  162.  
  163. /********************************************************************
  164. *
  165. *   Synopsis
  166. *    fieldtoboard(f, i, j, x, y)
  167. *        int f, i, j;
  168. *        int *x, *y;        return
  169. *
  170. *   Arguments
  171. *    f    field id between F0 and RIP;
  172. *    i, j    coordinates of the field;
  173. *    *x, *y    contains returned values of coordinates of the board;
  174. *
  175. *********************************************************************/
  176.  
  177. fieldtoboard(f, i, j, x, y)
  178. int f, i, j, *x, *y;
  179. {
  180.     switch (f) {
  181.       case F0:
  182.     *x = 335+j*50;
  183.     *y = 585+i*50;
  184.     break;
  185.       case F1:
  186.     *x = 585+i*50;
  187.     *y = 335+(4-j)*50;
  188.     break;
  189.       case F2:
  190.     *x = 335+(4-j)*50;
  191.     *y = 35+(5-i)*50;
  192.     break;
  193.       case F3:
  194.     *x = 35+(5-i)*50;
  195.     *y = 335+j*50;
  196.     break;
  197.       case MIDFIELD:
  198.     *x = 335+j*100;
  199.     *y = 335+i*100;
  200.     break;
  201.       case RIP:
  202.     *x = 60+j*50;
  203.     *y = 610+i*50;
  204.     }
  205. }
  206.  
  207.  
  208.  
  209. /**********************************************************************
  210. *
  211. *   Synopsis
  212. *    arrtoboard(id, g, i, j, x, y)
  213. *        int id, g, i, j;
  214. *        int *x, *y;        return
  215. *
  216. *   Arguments
  217. *    id    0-3, specifies the player of the board;
  218. *    g    F0 - RIP, which array;
  219. *    i, j    coordinates of the array;
  220. *    *x, *y  contains the results;
  221. *
  222. **********************************************************************/
  223.  
  224. arrtoboard(id, g, i, j, x, y)
  225. int id, g, i, j, *x, *y;
  226. {
  227.     int k;
  228.  
  229.     if (g==MIDFIELD)
  230.     switch (id) {
  231.       case 1:
  232.         k = i;  i = j;  j = 2-k;
  233.         break;
  234.       case 2:
  235.         i = 2-i;  j = 2-j;
  236.         break;
  237.       case 3:
  238.         k = i;  i = 2-j; j = k;
  239.     }
  240.     else if (g != RIP) {
  241.     g -= id;
  242.     if (g<0) g += 4;
  243.     }
  244.     fieldtoboard(g,i,j,x,y);
  245. }
  246.  
  247.  
  248.  
  249.  
  250.  
  251. /*********************************************************************
  252. *
  253. *   Synopsis
  254. *    int fieldtoarr(id, f, fi, fj, ai, aj)
  255. *        int id, f, fi, fj;
  256. *        int *ai, *aj;
  257. *
  258. *   Arguments
  259. *    id    0-3, the player of the board;
  260. *    f    F0 - RIP, field number;
  261. *    fi, fj    coordinates in the field;
  262. *    *ai, *aj    result coordinates of the array;
  263. *
  264. *   Return value
  265. *    returns which array is resulted
  266. *
  267. **********************************************************************/
  268.  
  269. int fieldtoarr(id, f, fi, fj, ai, aj)
  270. int id, f, fi, fj, *ai, *aj;
  271. {
  272.     *ai = fi;
  273.     *aj = fj;
  274.     if ( f==MIDFIELD )
  275.     switch (id) {
  276.       case 1:
  277.         *ai = 2-fj; *aj = fi;
  278.         break;
  279.       case 2:
  280.         *ai = 2 - fi; *aj = 2 - fj;
  281.         break;
  282.       case 3:
  283.         *ai = fj;  *aj = 2 - fi;
  284.     }
  285.     return((f>=F0 && f<MIDFIELD) ? (f+id)%4 : f);
  286. }
  287.  
  288.  
  289.  
  290. /*********************************************************************
  291. *
  292. *   Synopsis
  293. *    int boardtoarr(f, x, y, i, j)
  294. *        int f, x, y, *i, *j;
  295. *
  296. *   Arguments
  297. *    f    specifies who's board;
  298. *    x, y    the coordinates on board;
  299. *    *i, *j    return the coordinates in the array;
  300. *
  301. *   Return value
  302. *    it returns which array the point corresponds.
  303. *    returns -1 if no array to match.
  304. *
  305. **********************************************************************/
  306.  
  307. int boardtoarr(f, x, y, i, j)
  308. int f, x, y, *i, *j;
  309. {
  310.     int m, n, s;
  311.  
  312.     s = boardtofield(x, y, &m, &n);
  313.     if (s > RIP) return(-1);
  314.     s = fieldtoarr(f, s, m, n, i, j);
  315.     return(s);
  316. }
  317.  
  318.  
  319.  
  320.  
  321. /************************************************************************
  322. *
  323. *   Synopsis
  324. *    int area_intersection(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2,
  325. *        cx1, cy1, cx2, cy2)
  326. *        int ax1, ay1, ax2, ay2, bx1, by1, bx2, by2;
  327. *        int *cx1, *cy1, *cx2, *cy2;        return
  328. *
  329. *   Arguments
  330. *    a's and b's:    coordinates of two rectangles;
  331. *    c's        contains the coordinates of the intersection area;
  332. *
  333. *   Return values
  334. *    1    if the two rectangles intersect, and c's are set;
  335. *    0    if the two rectangles not intersect;
  336. *
  337. **************************************************************************/
  338.  
  339. int area_intersection(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2,
  340.         cx1, cy1, cx2, cy2)
  341. int ax1, ay1, ax2, ay2, bx1, by1, bx2, by2, *cx1, *cy1, *cx2, *cy2;
  342. {
  343.     int k;
  344.  
  345.     if (ax1>ax2) {
  346.     k = ax1; ax1 = ax2; ax2 = k;
  347.     }
  348.     if (ay1>ay2) {
  349.     k = ay1; ay1 = ay2; ay2 = k;
  350.     }
  351.     if (bx1>bx2) {
  352.     k = bx1; bx1 = bx2; bx2 = k;
  353.     }
  354.     if (by1>by2) {
  355.     k = by1; by1 = by2; by2 = k;
  356.     }
  357.     *cx2 = (ax2<bx2) ? ax2 : bx2;
  358.     *cy2 = (ay2<by2) ? ay2 : by2;
  359.     if (ax1<=bx1 && ay1<=by1 && bx1<ax2 && by1<ay2) {
  360.     *cx1 = bx1;  *cy1 = by1;
  361.     return(1);
  362.     }
  363.     if (ax1<=bx1 && ay1>by1 && ay1<by2 && ax2>bx1) {
  364.     *cx1 = bx1; *cy1 = ay1;
  365.     return(1);
  366.     }
  367.     if (ax1>bx1 && ay1>by1 && ax1<bx2 && ay1<by2) {
  368.     *cx1 = ax1; *cy1 = ay1;
  369.     return(1);
  370.     }
  371.     if (ax1>bx1 && ay1<by1 && ax1<bx2 && ay2>by1) {
  372.     *cx1 = ax1; *cy1 = by1;
  373.     return(1);
  374.     }
  375.     return(0);
  376. }
  377.  
  378.  
  379.  
  380.  
  381. /**********************************************************************
  382. *
  383. *   Synopsis
  384. *    int sapper_check(i, x, y, z)
  385. *        int i, x, y, z;
  386. *
  387. *   Arguments
  388. *    i    start check from i of sap[];
  389. *    x, y, z the destination;
  390. *
  391. *   Return values
  392. *    0    if cannot reach destination;
  393. *    1    if can reach destination;
  394. *
  395. *   Side effect
  396. *    mark all visited nodes to round.
  397. *
  398. *   Description
  399. *    it recursively checks if a SAPPER can reach a destination, starting
  400. *    from a position in sap[i]; sap[i] must not have been visited, and
  401. *    the starting position must not be the destination.
  402. *
  403. ***********************************************************************/
  404.  
  405. int sapper_check(i, x, y, z)
  406. int i, x, y, z;
  407. {
  408.     int m, n, a, b, c, j;
  409.  
  410.     sap[i].visited = round;
  411.     m = 0;
  412.     if (i<12) {
  413.     a = i/3;
  414.     c = 2*(i%3);
  415.     if (c==0) {
  416.         n = (a-1);
  417.         if (n<0)  n = 3;
  418.         if (y==0 && z==4 && x==n)  return(1);
  419.         if (sap[n*3+2].visited != round && arr[n][0][4].value == EMPTY)
  420.         m = sapper_check(n*3+2, x, y, z);
  421.         if (m) return(1);
  422.  
  423.         n = sap[i].neighbor[0];
  424.         b = (n-12)/3;
  425.         c = (n-12)%3;
  426.         if (x==MIDFIELD && y==b && z==c)  return(1);
  427.         if (sap[n].visited != round && mid[b][c].value == EMPTY)
  428.         m = sapper_check(n, x, y, z);
  429.         if (m) return(1);
  430.  
  431.         if (x==a && y==0 && z==1)  return(1);
  432.         if (arr[a][0][1].value == EMPTY) {
  433.         if (x==a && y==0 && z==2)  return(1);
  434.         if (sap[a*3+1].visited != round && arr[a][0][2].value == EMPTY)
  435.             m = sapper_check(a*3+1, x, y, z);
  436.         if (m) return(1);
  437.         }
  438.  
  439.         if (a==x || sap[a*3+2].visited != round) {
  440.         if (a==x && z==0) {
  441.             for (j=1; j<y; j++)
  442.             if (arr[a][j][0].value != EMPTY) return(0);
  443.             return(1);
  444.         }
  445.         for (j=1; j<5; j++)
  446.             if (arr[a][j][0].value != EMPTY) return(0);
  447.         if (a==x && y==4) {
  448.             for (j=1; j<z; j++)
  449.             if (arr[a][4][j].value != EMPTY) return(0);
  450.             return(1);
  451.         }
  452.         for (j=1; j<5; j++)
  453.             if (arr[a][4][j].value != EMPTY) return(0);
  454.         if (a==x && z==4) {
  455.             for (j=y+1; j<4; j++)
  456.             if (arr[a][j][4].value != EMPTY) return(0);
  457.             return(1);
  458.         }
  459.         if (sap[a*3+2].visited == round) return(0);
  460.         for (j=0; j<4; j++)
  461.             if (arr[a][j][4].value != EMPTY) return(0);
  462.         return(sapper_check(a*3+2, x, y, z));
  463.         }
  464.         return(0);
  465.     }
  466.     if (c==2) {
  467.         if (a==x && y==0 && z==1)  return(1);
  468.         if (arr[a][0][1].value == EMPTY) {
  469.         if (a==x && y==0 && z==0)  return(1);
  470.         if (sap[a*3].visited != round && arr[a][0][0].value == EMPTY)
  471.             m = sapper_check(a*3, x, y, z);
  472.         if (m) return(1);
  473.         }
  474.         n = sap[i].neighbor[0];
  475.         b = (n-12)/3;
  476.         c = (n-12)%3;
  477.         if (x==MIDFIELD && y==b && z==c)  return(1);
  478.         if (sap[n].visited != round && mid[b][c].value == EMPTY)
  479.         m = sapper_check(n, x, y, z);
  480.         if (m) return(1);
  481.  
  482.         if (a==x && y==0 && z==3)  return(1);
  483.         if (arr[a][0][3].value == EMPTY) {
  484.         if (a==x && y==0 && z==4)  return(1);
  485.         if (sap[a*3+2].visited != round && arr[a][0][4].value == EMPTY)
  486.             m = sapper_check(a*3+2, x, y, z);
  487.         if (m) return(1);
  488.         }
  489.         return(0);
  490.     }
  491.     /* now c==4 */
  492.     if (a==x && y==0 && z==3)  return(1);
  493.     if (arr[a][0][3].value == EMPTY) {
  494.         if (a==x && y==0 && z==2)  return(1);
  495.         if (sap[a*3+1].visited != round && arr[a][0][2].value == EMPTY)
  496.         m = sapper_check(a*3+1, x, y, z);
  497.         if (m) return(1);
  498.     }
  499.     n = sap[i].neighbor[0];
  500.     b = (n-12)/3;
  501.     c = (n-12)%3;
  502.     if (x==MIDFIELD && b==y && c==z)  return(1);
  503.     if (sap[n].visited != round && mid[b][c].value == EMPTY)
  504.         m = sapper_check(n, x, y, z);
  505.     if (m) return(1);
  506.     n = (a+1)%4;
  507.     if (x==n && y==0 && z==0)  return(1);
  508.     if (sap[n*3].visited != round && arr[n][0][0].value == EMPTY)
  509.         m = sapper_check(n*3, x, y, z);
  510.     if (m) return(1);
  511.  
  512.     if (sap[a*3].visited != round || a==x) {
  513.         if (a==x && z==4) {
  514.         for (j=1; j<y; j++)
  515.             if (arr[a][j][4].value != EMPTY) return(0);
  516.         return(1);
  517.         }
  518.         for (j=1; j<5; j++)
  519.         if (arr[a][j][4].value != EMPTY) return(0);
  520.         if (a==x && y==4) {
  521.         for (j=z+1; j<4; j++)
  522.             if (arr[a][4][j].value != EMPTY) return(0);
  523.         return(1);
  524.         }
  525.         for (j=0; j<4; j++)
  526.         if (arr[a][4][j].value != EMPTY) return(0);
  527.         if (a==x && z==0) {
  528.         for (j=y+1; j<4; j++)
  529.             if (arr[a][j][0].value != EMPTY) return(0);
  530.         return(1);
  531.         }
  532.         if (sap[a*3].visited == round) return(0);
  533.         for (j=0; j<4; j++)
  534.         if (arr[a][j][0].value != EMPTY) return(0);
  535.         return(sapper_check(a*3, x, y, z));
  536.     }
  537.     return(0);
  538.     }
  539.     else {    /* starting position in the MIDFIELD */
  540.     j = 0;
  541.     while (!m && j<4) {
  542.         n = sap[i].neighbor[j];
  543.         if (sap[n].visited != round)
  544.         if (n<12) {
  545.             a = n/3;
  546.             c = 2*(n%3);
  547.             if (x==a && y==0 && z==c) return(1);
  548.             if (arr[a][0][c].value == EMPTY)
  549.             m = sapper_check(n, x, y, z);
  550.         }
  551.         else {
  552.             b = (n-12)/3;
  553.             c = (n-12)%3;
  554.             if (x==MIDFIELD && y==b && z==c)  return(1);
  555.             if (mid[b][c].value == EMPTY)
  556.             m = sapper_check(n, x, y, z);
  557.         }
  558.         j++;
  559.     }
  560.     return(m);
  561.     }
  562. }
  563.  
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571. /**********************************************************************
  572. *
  573. *   Synopsis
  574. *    int valid_move(a, b, c, x, y, z)
  575. *        int a, b, c, x, y, z;
  576. *
  577. *   Return values
  578. *    1    for valid move;
  579. *    0    for invalid move;
  580. *
  581. *   Description
  582. *    It checks if a move as (a,b,c)=>(x,y,z) is valid according to
  583. *    the positions;
  584. *
  585. ***********************************************************************/
  586.  
  587. int valid_move(a, b, c, x, y, z)
  588. int a, b, c, x, y, z;
  589. {
  590.     int m, n, i, l;
  591.  
  592.     if ((a<MIDFIELD && x<MIDFIELD) && (b==5 || y==5 ||
  593.         (0<b && b<4 && 0<c && c<4) || (0<y && y<4 && 0<z && z<4))) {
  594.     /* can move only one step far */
  595.     if (a != x) return(0);
  596.     m = abs(b-y) + abs(c-z);
  597.     if (m<1 || m>2)  return(0);
  598.     if ( (abs(b-y)<2 && abs(c-z)<2) &&
  599.         (((b==1 || b==3) && (c==1 || c==3)) || (b==2 && c==2) ||
  600.         ((y==1 || y==3) && (z==1 || z==3)) || (y==2 && z==2)))
  601.         return(1);
  602.     if (m == 1) return(1);
  603.     else return(0);
  604.     }
  605.  
  606. /* from now on, the source and the destination are both on the railway */
  607.     if (a==MIDFIELD && mid[b][c].value == SAPPER ||
  608.     a<MIDFIELD && arr[a][b][c].value == SAPPER) {
  609.     round++;
  610.     m = 0;
  611.     if (a<MIDFIELD && (b!=0 || (b==0 && (c==1 || c==3)))) {
  612.         if (b==0)
  613.         if (c==1) {
  614.             if (x==a && y==0 && (z==0 || z==2)) return(1);
  615.             if (arr[a][0][0].value == EMPTY)
  616.             m = sapper_check(a*3, x, y, z);
  617.             if (m) return(1);
  618.             if (sap[a*3+1].visited!=round && arr[a][0][2].value==EMPTY)
  619.             m = sapper_check(a*3+1, x, y, z);
  620.             return(m);
  621.         }
  622.         else {
  623.             if (x==a && y==0 && (z==2 || z==4)) return(1);
  624.             if (arr[a][0][2].value != EMPTY)
  625.             m = sapper_check(a*3+1, x, y, z);
  626.             if (m) return(1);
  627.             if (sap[a*3+2].visited!=round && arr[a][0][4].value==EMPTY)
  628.             m = sapper_check(a*3+2, x, y, z);
  629.             return(m);
  630.         }
  631.         else
  632.         if (c==0 || c==4) {
  633.             if (a==x && z==c && y<b) {
  634.             for (i=y+1; i<b; i++)
  635.                 if (arr[a][i][c].value != EMPTY) break;
  636.             if (i==b) return(1);
  637.             }
  638.             else {
  639.             for (i=0; i<b; i++)
  640.                 if (arr[a][i][c].value != EMPTY) break;
  641.             if (i==b)
  642.                 m = sapper_check(a*3+(c/2), x, y, z);
  643.             if (m) return(1);
  644.             }
  645.             if (a==x || sap[a*3].visited != round ||
  646.                 sap[a*3+2].visited != round) {
  647.             if (a==x && z==c && y>b) {
  648.                 for (i=b+1; i<y; i++)
  649.                 if (arr[a][i][c].value != EMPTY) return(0);
  650.                 return(1);
  651.             }
  652.             for (i=b+1; i<5; i++)
  653.                 if (arr[a][i][c].value != EMPTY) return(0);
  654.             if (a==x && y==4)
  655.                 if (c==0) {
  656.                 for (i=1; i<z; i++)
  657.                     if (arr[a][4][i].value != EMPTY) return(0);
  658.                 return(1);
  659.                 }
  660.                 else {
  661.                 for (i=z+1; i<4; i++)
  662.                     if (arr[a][4][i].value != EMPTY) return(0);
  663.                 return(1);
  664.                 }
  665.             n = (c==0) ? 1 : 0;
  666.             for (i=0; i<4; i++)
  667.                 if (arr[a][4][i+n].value != EMPTY) return(0);
  668.             n = (c==0) ? 4 : 0;
  669.             if (a==x && n==z) {
  670.                 for (i=y+1; i<4; i++)
  671.                 if (arr[a][i][n].value != EMPTY) return(0);
  672.                 return(1);
  673.             }
  674.             if (sap[a*3+n/2].visited == round) return(0);
  675.             for (i=0; i<4; i++)
  676.                 if (arr[a][i][n].value != EMPTY) return(0);
  677.             return(sapper_check(a*3+n/2, x, y, z));
  678.             }
  679.             return(0);
  680.         }
  681.         else {        /* starting point is at the second bottom line */
  682.             if (a==x && y==4 && z<c) {
  683.             for (i=z+1; i<c; i++)
  684.                 if (arr[a][4][i].value != EMPTY) break;
  685.             if (i==c) return(1);
  686.             }
  687.             else
  688.             for (i=0; i<c; i++)
  689.                 if (arr[a][4][i].value != EMPTY) break;
  690.             if (i==c) {
  691.             if (a==x && y<4 && z==0) {
  692.                 for (i=y+1; i<4; i++)
  693.                 if (arr[a][i][0].value != EMPTY) break;
  694.                 if (i==4) return(1);
  695.             }
  696.             else
  697.                 for (i=0; i<4; i++)
  698.                 if (arr[a][i][0].value != EMPTY) break;
  699.             if (i==4) {
  700.                 m = sapper_check(a*3, x, y, z);
  701.                 if (m) return(1);
  702.             }
  703.             }
  704.             if (a==x || sap[a*3].visited != round ||
  705.                 sap[a*3+2].visited != round) {
  706.             if (a==x && y==4 && z>c) {
  707.                 for (i=c+1; i<z; i++)
  708.                 if (arr[a][4][i].value != EMPTY) return(0);
  709.                 return(1);
  710.             }
  711.             for (i=c+1; i<5; i++)
  712.                 if (arr[a][4][i].value != EMPTY) return(0);
  713.             if (a==x && y<4 && z==4) {
  714.                 for (i=y+1; i<4; i++)
  715.                 if (arr[a][i][4].value != EMPTY) return(0);
  716.                 return(1);
  717.             }
  718.             if (sap[a*3+2].visited==round) return(0);
  719.             for (i=0; i<4; i++)
  720.                 if (arr[a][i][4].value != EMPTY) return(0);
  721.             return(sapper_check(a*3+2, x, y, z));
  722.             }
  723.             return(0);
  724.         }
  725.     }
  726.     else
  727.         if (a<4)  return(sapper_check(a*3+c/2, x, y, z));
  728.         else return(sapper_check(12+b*3+c, x, y, z));
  729.     }
  730.  
  731.  
  732. /* now the moving node is not a SAPPER */
  733.  
  734.     if (a<MIDFIELD && a==x) {
  735.     if (b==y && (b==0 || b==4)) {
  736.         if (c < z) {
  737.         m = c;  n = z;
  738.         }
  739.         else {
  740.         m = z;  n = c;
  741.         }
  742.         for (i=m+1; i<n; i++)
  743.         if (arr[a][b][i].value != EMPTY)  return(0);
  744.         return(1);
  745.     }
  746.     else if (c==z && (c==0 || c==4)) {
  747.         if (b < y) {
  748.         m = b;  n = y;
  749.         }
  750.         else {
  751.         m = y;  n = b;
  752.         }
  753.         for (i=m+1; i<n; i++)
  754.         if (arr[a][i][c].value != EMPTY) return(0);
  755.         return(1);
  756.     }
  757.     else return(0);
  758.     }
  759.  
  760. /* from now on the source and the destination are on different fields */
  761.     if (a != MIDFIELD)
  762.     if (c==0 || c==4) {
  763.         for (i=0; i<b; i++)
  764.         if (arr[a][i][c].value != EMPTY) return(0);
  765.     }
  766.     else
  767.         if (b!=0 || c!=2) return(0);
  768.     if (x != MIDFIELD)
  769.     if (z==0 || z==4) {
  770.         for (i=0; i<y; i++)
  771.         if (arr[x][i][z].value != EMPTY) return(0);
  772.     }
  773.     else
  774.         if (y!=0 || z!=2) return(0);
  775.  
  776.     if (a<MIDFIELD && x<MIDFIELD) {
  777.     if ((x+1)%4 == a)
  778.         if (z==4 && c==0)  return(1);
  779.         else return(0);
  780.     else if ((a+1)%4 == x)
  781.         if (z==0 && c==4) return(1);
  782.         else return(0);
  783.     if (!((c==0 && z==4) || (c==4 && z==0) || (c==2 && z==2)))
  784.         return(0);
  785.     }
  786.  
  787. /* now the move has to go across the MIDFIELD */
  788.     if ((a<MIDFIELD && a%2==0) || (x<MIDFIELD && x%2==0) ||
  789.     (a==MIDFIELD && x==MIDFIELD && c==z)) {
  790.     if (a != MIDFIELD) {
  791.         if (a==F0) {
  792.         l = c/2;
  793.         n = 2;
  794.         m = (x==MIDFIELD) ? (y+1) : 0;
  795.         }
  796.         else {
  797.         l = (4-c)/2;
  798.         m = 0;
  799.         n = (x==MIDFIELD) ? (y-1) : 2;
  800.         }
  801.         if (x==MIDFIELD && l!=z) return(0);
  802.     }
  803.     else
  804.         if (x != MIDFIELD) {
  805.         if (x==F0) {
  806.             l = z/2;
  807.             m = b+1;
  808.             n = 2;
  809.         }
  810.         else {
  811.             l = (4-z)/2;
  812.             m = 0;
  813.             n = b-1;
  814.         }
  815.         if (l != c)  return(0);
  816.         }
  817.         else {
  818.         l = z;
  819.         if (b<y) {
  820.             m = b+1; n = y-1;
  821.         }
  822.         else {
  823.             m = y+1; n = b-1;
  824.         }
  825.         }
  826.  
  827.     for (i=m; i<=n; i++)
  828.         if (mid[i][l].value != EMPTY) return(0);
  829.     return(1);
  830.     }
  831.  
  832.     if ((a<MIDFIELD && a%2!=0) || (x<MIDFIELD && x%2!=0) ||
  833.     (a==MIDFIELD && x==MIDFIELD && b==y)) {
  834.     if (a != MIDFIELD) {
  835.         if (a==F1) {
  836.         l = (4-c)/2;
  837.         n = 2;
  838.         m = (x==MIDFIELD) ? (z+1) : 0;
  839.         }
  840.         else {
  841.         l = c/2;
  842.         m = 0;
  843.         n = (x==MIDFIELD) ? (z-1) : 2;
  844.         }
  845.         if (x == MIDFIELD && l != y) return(0);
  846.     }
  847.     else
  848.         if (x != MIDFIELD) {
  849.         if (x==F1) {
  850.             l = (4-z)/2;
  851.             m = c+1;
  852.             n = 2;
  853.         }
  854.         else {
  855.             l = z/2;
  856.             m = 0;
  857.             n = c-1;
  858.         }
  859.         if (l != b)  return(0);
  860.         }
  861.         else {
  862.         l = b;
  863.         if (c<z) {
  864.             m = c+1; n = z-1;
  865.         }
  866.         else {
  867.             m = z+1; n = c-1;
  868.         }
  869.         }
  870.  
  871.  
  872.     for (i=m; i<=n; i++)
  873.         if (mid[l][i].value != EMPTY) return(0);
  874.     return(1);
  875.     }
  876.  
  877.     return(0);
  878. }
  879.  
  880.  
  881. /*************************************************************************
  882. *
  883. *   Synopsis
  884. *    initial_sapper()
  885. *
  886. *   Description
  887. *    initializes the array 'sap' of the sapper move checking path.
  888. *
  889. **************************************************************************/
  890.  
  891. initial_sapper()
  892. {
  893.     int i;
  894.  
  895.     round = 0;
  896.  
  897.     for (i=0; i<21; i++)
  898.     sap[i].visited = 0;
  899.  
  900.     sap[0].neighbor[0] = 18;
  901.     sap[1].neighbor[0] = 19;
  902.     sap[2].neighbor[0] = 20;
  903.     sap[3].neighbor[0] = 20;
  904.     sap[4].neighbor[0] = 17;
  905.     sap[5].neighbor[0] = 14;
  906.     sap[6].neighbor[0] = 14;
  907.     sap[7].neighbor[0] = 13;
  908.     sap[8].neighbor[0] = 12;
  909.     sap[9].neighbor[0] = 12;
  910.     sap[10].neighbor[0] = 15;
  911.     sap[11].neighbor[0] = 18;
  912.  
  913.     sap[12].neighbor[0] = 9;
  914.     sap[12].neighbor[1] = 8;
  915.     sap[12].neighbor[2] = 13;
  916.     sap[12].neighbor[3] = 15;
  917.     sap[13].neighbor[0] = 12;
  918.     sap[13].neighbor[1] = 7;
  919.     sap[13].neighbor[2] = 14;
  920.     sap[13].neighbor[3] = 16;
  921.     sap[14].neighbor[0] = 13;
  922.     sap[14].neighbor[1] = 6;
  923.     sap[14].neighbor[2] = 5;
  924.     sap[14].neighbor[3] = 17;
  925.  
  926.     sap[15].neighbor[0] = 10;
  927.     sap[15].neighbor[1] = 12;
  928.     sap[15].neighbor[2] = 16;
  929.     sap[15].neighbor[3] = 18;
  930.     sap[16].neighbor[0] = 15;
  931.     sap[16].neighbor[1] = 13;
  932.     sap[16].neighbor[2] = 17;
  933.     sap[16].neighbor[3] = 19;
  934.     sap[17].neighbor[0] = 16;
  935.     sap[17].neighbor[1] = 14;
  936.     sap[17].neighbor[2] = 4;
  937.     sap[17].neighbor[3] = 20;
  938.  
  939.     sap[18].neighbor[0] = 11;
  940.     sap[18].neighbor[1] = 15;
  941.     sap[18].neighbor[2] = 19;
  942.     sap[18].neighbor[3] = 0;
  943.     sap[19].neighbor[0] = 18;
  944.     sap[19].neighbor[1] = 16;
  945.     sap[19].neighbor[2] = 20;
  946.     sap[19].neighbor[3] = 1;
  947.     sap[20].neighbor[0] = 19;
  948.     sap[20].neighbor[1] = 17;
  949.     sap[20].neighbor[2] = 3;
  950.     sap[20].neighbor[3] = 2;
  951. }
  952.  
  953.  
  954.  
  955.  
  956.  
  957.