Annotation of 43BSDReno/games/chess/move.c, revision 1.1.1.1

1.1       root        1: /* move generator [email protected] 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: } 
                    357: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.