|
6 | 6 |
|
7 | 7 | char c[Q], *C, |
8 | 8 | *T="#6*.683234#15BD#24#24$3#(.)$?).(/.2##$"; // Piece move steps, board setup data and promotion XORs (subtract '#'=35). |
9 | | -B[Q], S, W, X; |
| 9 | +B[Q], R, S, W, X; |
10 | 10 |
|
11 | | -F(U, V, p) { |
12 | | - int f=0,t, i, d, P, u; |
| 11 | +F(U, V, p, r) { |
| 12 | + int f=0,t, i, d, P, u, q; |
13 | 13 | for(;f<128;f=f+9&~8) { // Loop over squares looking for pieces. |
14 | 14 | for(i=T[(P=B[f])&7]-35,d=0;d<0 || (d=T[i++]-35);d=-d) { // Loop over move steps for this piece. |
15 | 15 | for(t=f+d;P&S;t+=d) { // Loop over destination squares in this direction. |
16 | 16 | // Invalid square or friendly capture? |
17 | 17 | if ((t&136) || ((u=B[t])&S)) |
18 | 18 | break; |
19 | 19 |
|
20 | | - // Check for correct pawn movement. |
21 | | - if (P%8==2 && ((d^(u>0))%2 || ((d>0)^(S==32)))) |
22 | | - break; |
| 20 | + // Special pawn logic. |
| 21 | + q=128; |
| 22 | + if (P%8==2) |
| 23 | + { |
| 24 | + if (((d>0)^(S==32)) || // Bad direction? |
| 25 | + (!u && d%2 && t!=r) || // Diagonal without capture? |
| 26 | + (!(d%2) && u>0)) // Straight with capture? |
| 27 | + break; |
| 28 | + |
| 29 | + q=(t==r ? 16 : q); // Is this an en-passent capture? |
| 30 | + } |
23 | 31 |
|
24 | 32 | // Other side left in check? |
25 | 33 | if (U==8 && (u&16)) |
26 | 34 | return 0; |
| 35 | + |
27 | 36 | // Make move. |
28 | 37 | B[t]=P; |
| 38 | + B[f]=0; |
| 39 | + B[t^q]=0; // If en-passent capture, remove victim pawn. |
29 | 40 | if (P%8==2 && (t<8 || t>103)) |
30 | 41 | B[t]^=T[p%7+32]-35; // Promotion. |
31 | | - B[f]=0; |
32 | 42 | S^=96; |
33 | 43 | if ((P&16) && t!=f+d) |
34 | 44 | B[(f+t)/2]=B[t+(d>0?1:-2)],B[t+(d>0?1:-2)]=0; // If castling also move rook. |
35 | 45 |
|
36 | 46 | // Looking to make a move? (if our own move, make sure does not leave us in check) |
37 | 47 | if ((t==V && f==U) || (U==Q && F(8,0,0,Q))) { |
38 | 48 | W=f,X=t; |
| 49 | + R=((P%8==2 && t!=f+d) ? (t+f)/2 : 9); // Set ep-target square if double pawn move. |
39 | 50 | return B[t]==P; // Indicate if promotion has NOT occured. |
40 | 51 | } |
41 | 52 |
|
42 | 53 | // Undo move. |
| 54 | + B[t^q]=10|S; // If en-passent capture, replace victim pawn. |
43 | 55 | S^=96; |
44 | 56 | B[f]=P; |
45 | 57 | B[t]=u; |
@@ -68,14 +80,14 @@ main(i, p) { |
68 | 80 | Z"q",1)) break; // Quit command, exit. |
69 | 81 | Z"p",1)) { // Parse 'position' command. |
70 | 82 | for(i=0;i<8;++i) // Reset board to start position. |
71 | | - B[i+16]=42,B[i+96]=74, // Pawns. |
| 83 | + B[i+16]=R=42,B[i+96]=74, // Pawns. |
72 | 84 | B[i+112]=(B[i]=T[i+24]-3)+(S=32), // Pieces. |
73 | 85 | B[i+S]=B[i+48]=B[i+64]=B[i+80]=0; // Empty rows. |
74 | 86 | for(;C=strtok(0," ");) |
75 | | - F(*C+C[1]*16-881, C[2]+C[3]*16-881, C[4]); |
| 87 | + F(*C+C[1]*16-881, C[2]+C[3]*16-881, C[4], R); |
76 | 88 | } |
77 | 89 | Z"g",1)) // Go command. Make a move and print it. |
78 | | - p=F(Q, 0, 0), |
| 90 | + p=F(Q, 0, 0, R), |
79 | 91 | printf("bestmove %c%i%c%i%c\n", W%16+97, W/16+1, X%16+97, X/16+1, p?32:98); |
80 | 92 | } |
81 | 93 | } |
0 commit comments