|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.