home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / games / chess / move.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-01  |  8.4 KB  |  358 lines

  1. /* move generator hes@log-sv.se 890318
  2.    Modified: 890606 NEWMOVE Levels 1-6 for easier debugging */
  3. #include "move.h"
  4. #include "gnuchess.h"
  5.  
  6. short distdata[64][64];
  7. short taxidata[64][64];
  8.  
  9. void Initialize_dist() {
  10. register short a,b,d,di;
  11.  
  12.   /* init taxi and dist data */
  13.   for(a=0;a<64;a++)
  14.     for(b=0;b<64;b++) {
  15.       d = abs(column[a]-column[b]);
  16.       di = abs(row[a]-row[b]);
  17.       taxidata[a][b] = d + di;
  18.       distdata[a][b] = (d > di ? d : di);
  19.     };
  20. }
  21.  
  22. #if (NEWMOVE > 1)
  23. struct sqdata posdata[3][8][64][64];
  24.  
  25. static short direc[8][8] = {
  26.     0,  0,  0,  0,  0,  0,  0,  0, /* no_piece = 0 */
  27.   -10,-11, -9,  0,  0,  0,  0,  0, /* wpawn    = 1 */
  28.   -21,-19,-12, -8, 21, 19, 12,  8, /* knight   = 2 */
  29.   -11, -9, 11,  9,  0,  0,  0,  0, /* bishop   = 3 */
  30.   -10, -1, 10,  1,  0,  0,  0,  0, /* rook     = 4 */
  31.   -11, -9,-10, -1, 11,  9, 10,  1, /* queen    = 5 */
  32.   -11, -9,-10, -1, 11,  9, 10,  1, /* king     = 6 */
  33.     0,  0,  0,  0,  0,  0,  0,  0};/* no_piece = 7 */
  34.  
  35. static short dc[3] = {-1,1,0};
  36.  
  37. static short max_steps [8] = {0,2,1,7,7,7,1,0};
  38.  
  39. static short unmap[120] = {
  40.   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  41.   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  42.   -1, 0, 1, 2, 3, 4, 5, 6, 7,-1,
  43.   -1, 8, 9,10,11,12,13,14,15,-1,
  44.   -1,16,17,18,19,20,21,22,23,-1,
  45.   -1,24,25,26,27,28,29,30,31,-1,
  46.   -1,32,33,34,35,36,37,38,39,-1,
  47.   -1,40,41,42,43,44,45,46,47,-1,
  48.   -1,48,49,50,51,52,53,54,55,-1,
  49.   -1,56,57,58,59,60,61,62,63,-1,
  50.   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  51.   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
  52.  
  53. void Initialize_moves() {
  54.   short c,ptyp,po,p0,d,di,s;
  55.   struct sqdata *p;
  56.   short dest[8][8];
  57.   short steps[8];
  58.   short sorted[8];
  59.  
  60.   /* init posdata */
  61.   for(c=0;c<3;c++)
  62.     for(ptyp=0;ptyp<8;ptyp++)
  63.       for(po=0;po<64;po++)
  64.     for(p0=0;p0<64;p0++) {
  65.       posdata[c][ptyp][po][p0].nextpos = po;
  66.       posdata[c][ptyp][po][p0].nextdir = po;
  67.     };
  68.   /* dest is a function of dir and step */
  69.   for(c=0;c<2;c++)
  70.     for(ptyp=1;ptyp<7;ptyp++)
  71.       for(po=21;po<99;po++)
  72.     if (unmap[po] >= 0) {
  73.           p = posdata[c][ptyp][unmap[po]];
  74.       for(d=0;d<8;d++) {
  75.         dest[d][0] = unmap[po];
  76.         if (dc[c]*direc[ptyp][d] != 0) {
  77.           p0=po;
  78.           for(s=0;s<max_steps[ptyp];s++) {
  79.         p0 = p0 + dc[c]*direc[ptyp][d];
  80.         /* break if (off board) or
  81.            (pawns move two steps from home square) */
  82.         if (unmap[p0] < 0 ||
  83.             (ptyp == pawn && s>0 && (d>0 || Stboard[unmap[po]] != ptyp)))
  84.           break;
  85.         else
  86.           dest[d][s] = unmap[p0];
  87.           }
  88.         }
  89.         else s=0;
  90.         /* sort dest in number of steps order */
  91.         steps[d] = s;
  92.         for(di=d;di>0;di--)
  93.           if (steps[sorted[di-1]] < s)
  94.         sorted[di] = sorted[di-1];
  95.           else
  96.         break;
  97.         sorted[di] = d;
  98.       }
  99.       /* update posdata, pawns have two threads (capture and no capture) */
  100.       p0=unmap[po];
  101.       if (ptyp == pawn) {
  102.         for(s=0;s<steps[0];s++) {
  103.           p[p0].nextpos = dest[0][s];
  104.           p0 = dest[0][s];
  105.         }
  106.         p0=unmap[po];
  107.         for(d=1;d<3;d++) {
  108.           p[p0].nextdir = dest[d][0];
  109.           p0 = dest[d][0];
  110.         }
  111.       }
  112.       else {
  113.         p[p0].nextdir = dest[sorted[0]][0];
  114.         for(d=0;d<8;d++)
  115.           for(s=0;s<steps[sorted[d]];s++) {
  116.         p[p0].nextpos = dest[sorted[d]][s];
  117.         p0 = dest[sorted[d]][s];
  118.         if (d < 7)
  119.           p[p0].nextdir = dest[sorted[d+1]][0];
  120.         /* else is already initialised */
  121.           }
  122.       }
  123. #ifdef DEBUG
  124.       printf("Ptyp:%d Position:%d\n{",ptyp,unmap[po]);
  125.       for(p0=0;p0<63;p0++) printf("%d,",p[p0].nextpos);
  126.       printf("%d};\n",p[63].nextpos);
  127.       for(p0=0;p0<63;p0++) printf("%d,",p[p0].nextdir);
  128.       printf("%d};\n",p[63].nextdir);
  129. #endif DEBUG
  130.     }
  131. }
  132. #endif
  133.  
  134.  
  135. #if (NEWMOVE > 2)
  136. int SqAtakd(sq,side)
  137. short sq,side;
  138.  
  139. /*
  140.   See if any piece with color 'side' ataks sq. First check pawns
  141.   Then Queen, Bishop, Rook and King and last Knight.
  142. */
  143.  
  144. {
  145.   register short u;
  146.   register struct sqdata *p;
  147.  
  148.   p = posdata[1-side][pawn][sq];
  149.   u = p[sq].nextdir; /* follow captures thread */
  150.   while (u != sq) {
  151.     if (board[u] == pawn && color[u] == side) return(true);
  152.     u = p[u].nextdir;
  153.   }
  154.   /* king capture */
  155.   if (distance(sq,PieceList[side][0]) == 1) return(true);
  156.   /* try a queen bishop capture */
  157.   p = posdata[side][bishop][sq];
  158.   u = p[sq].nextpos;
  159.   while (u != sq) {
  160.     if (color[u] == neutral) {
  161.       u = p[u].nextpos;
  162.     }
  163.     else {
  164.       if (color[u] == side && 
  165.       (board[u] == queen || board[u] == bishop))
  166.     return(true);
  167.       u = p[u].nextdir;
  168.     }
  169.   }
  170.   /* try a queen rook capture */
  171.   p = posdata[side][rook][sq];
  172.   u = p[sq].nextpos;
  173.   while (u != sq) {
  174.     if (color[u] == neutral) {
  175.       u = p[u].nextpos;
  176.     }
  177.     else {
  178.       if (color[u] == side && 
  179.       (board[u] == queen || board[u] == rook))
  180.     return(true);
  181.       u = p[u].nextdir;
  182.     }
  183.   }
  184.   /* try a knight capture */
  185.   p = posdata[side][knight][sq];
  186.   u = p[sq].nextpos;
  187.   while (u != sq) {
  188.     if (color[u] == neutral) {
  189.       u = p[u].nextpos;
  190.     }
  191.     else {
  192.       if (color[u] == side && board[u] == knight) return(true);
  193.       u = p[u].nextdir;
  194.     }
  195.   }
  196.   return(false);
  197. }
  198. #endif
  199.  
  200. #if (NEWMOVE > 3)
  201. BRscan(sq,s,mob)
  202. short sq,*s,*mob;
  203. /*
  204.    Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the 
  205.    hung[] array if a pin is found. 
  206. */
  207. {
  208.   register short u,piece,pin;
  209.   register struct sqdata *p;
  210.   short *Kf;
  211.  
  212.   Kf = Kfield[c1];
  213.   *mob = 0;
  214.   piece = board[sq];
  215.   p = posdata[color[sq]][piece][sq];
  216.   u = p[sq].nextpos;
  217.   pin = -1; /* start new direction */
  218.   while (u != sq) {
  219.     *s += Kf[u];
  220.     if (color[u] == neutral) {
  221.       (*mob)++;
  222.       if (p[u].nextpos == p[u].nextdir) pin = -1; /* oops new direction */
  223.       u = p[u].nextpos;
  224.     }
  225.     else if (pin < 0) {
  226.       if (board[u] == pawn || board[u] == king)
  227.     u = p[u].nextdir;
  228.       else {
  229.     if (p[u].nextpos != p[u].nextdir)
  230.       pin = u; /* not on the edge and on to find a pin */
  231.     u = p[u].nextpos;
  232.       }
  233.     }
  234.     else if (color[u] == c2 && (board[u] > piece || atk2[u] == 0))
  235.       {
  236.     if (color[pin] == c2)
  237.       {
  238.         *s += PINVAL;
  239.         if (atk2[pin] == 0 ||
  240.         atk1[pin] > control[board[pin]]+1)
  241.           ++hung[c2];
  242.       }
  243.     else *s += XRAY;
  244.     pin = -1; /* new direction */
  245.     u = p[u].nextdir;
  246.       }
  247.     else {
  248.       pin = -1; /* new direction */
  249.       u = p[u].nextdir;
  250.     }
  251.   }
  252. }
  253. #endif
  254.  
  255. #if (NEWMOVE >= 5)
  256. CaptureList(side,xside,ply)
  257. short side,xside,ply;
  258. {
  259.   register short u,sq;
  260.   register struct sqdata *p;
  261.   short i,piece,*PL;
  262.   struct leaf *node;
  263.   
  264.   TrPnt[ply+1] = TrPnt[ply];
  265.   node = &Tree[TrPnt[ply]];
  266.   PL = PieceList[side];
  267.   for (i = 0; i <= PieceCnt[side]; i++)
  268.     {
  269.       sq = PL[i];
  270.       piece = board[sq];
  271.       p = posdata[side][piece][sq];
  272.       if (piece == pawn) {
  273.     u = p[sq].nextdir; /* follow captures thread */
  274.     while (u != sq) {
  275.       if (color[u] == xside) {
  276.             node->f = sq; node->t = u;
  277.             node->flags = capture;
  278.             if (u < 8 || u > 55)
  279.               {
  280.                 node->flags |= promote;
  281.                 node->score = valueQ;
  282.               }
  283.         else
  284.               node->score = value[board[u]] + svalue[board[u]] - piece;
  285.             ++node;
  286.             ++TrPnt[ply+1];
  287.            }
  288.       u = p[u].nextdir;
  289.     }
  290.       }
  291.       else {
  292.     u = p[sq].nextpos;
  293.     while (u != sq) {
  294.           if (color[u] == neutral)
  295.           u = p[u].nextpos;
  296.           else {
  297.           if (color[u] == xside) {
  298.               node->f = sq; node->t = u;
  299.               node->flags = capture;
  300.               node->score = value[board[u]] + svalue[board[u]] - piece;
  301.               ++node;
  302.               ++TrPnt[ply+1];
  303.              }
  304.        u = p[u].nextdir;
  305.      }
  306.        }
  307.      }
  308.    }
  309. }
  310. #endif
  311.  
  312. #if (NEWMOVE > 5)
  313. GenMoves(ply,sq,side,xside)
  314.      short ply,sq,side,xside;
  315.  
  316. /*
  317.   Generate moves for a piece. The moves are taken from the
  318.   precalulated array posdata. If the board is free, next move
  319.   is choosen from nextpos else from nextdir.
  320. */
  321.  
  322. {
  323.   register short u,piece;
  324.   register struct sqdata *p;
  325.      
  326.   piece = board[sq];
  327.   p = posdata[side][piece][sq];
  328.   if (piece == pawn) {
  329.     u = p[sq].nextdir; /* follow captures thread */
  330.     while (u != sq) {
  331.       if (color[u] == xside) LinkMove(ply,sq,u,xside);
  332.       u = p[u].nextdir;
  333.     }
  334.     u = p[sq].nextpos; /* and follow no captures thread */
  335.     while (u != sq) {
  336.       if (color[u] == neutral && (u != sq+16 || color[u-8] == neutral)
  337.           && (u != sq-16 || color[u+8] == neutral)) {
  338.         LinkMove(ply,sq,u,xside);
  339.       }
  340.       u = p[u].nextpos;
  341.     }
  342.   }  
  343.   else {
  344.     u = p[sq].nextpos;
  345.     while (u != sq) {
  346.       if (color[u] == neutral) {
  347.         LinkMove(ply,sq,u,xside);
  348.         u = p[u].nextpos;
  349.       }
  350.       else {
  351.         if (color[u] == xside) LinkMove(ply,sq,u,xside);
  352.     u = p[u].nextdir;
  353.       }
  354.     }
  355.   }    
  356. #endif
  357.