|
|
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.