2 * ataks.c - C source for GNU SHOGI
4 * Copyright (c) 1993, 1994, 1995 Matthias Mutz
6 * GNU SHOGI is based on GNU CHESS
8 * Copyright (c) 1988,1989,1990 John Stanback
9 * Copyright (c) 1992 Free Software Foundation
11 * This file is part of GNU SHOGI.
13 * GNU Shogi is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation.
17 * GNU Shogi is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with GNU Shogi; see the file COPYING. If not, write to
24 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
36 ataks (short int side, long int *a)
38 * Fill array atak[][] with info about ataks to a square. Bits 16-31 are set
39 * if the piece (king..pawn) ataks the square. Bits 0-15 contain a count of
40 * total ataks to the square.
49 register unsigned char *ppos, *pdir;
54 array_zero (a, NO_SQUARES * sizeof (a[0]));
57 for (i = PieceCnt[side]; i >= 0; i--)
61 ptyp = ptype[side][piece];
64 u = first_direction(ptyp,&d,sq);
66 ppos = (*nextpos[ptyp])[sq];
67 pdir = (*nextdir[ptyp])[sq];
71 a[u] = ((a[u]+1) | c);
73 u = ((color[u] == neutral) ? next_position(ptyp,&d,sq,u)
74 : next_direction(ptyp,&d,sq));
76 u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
85 #if defined DEBUG || defined DEBUG_EVAL
88 debug_ataks (FILE *D, long *atk)
92 for (l = NO_ROWS-1; l >= 0; l--) {
93 for (c = 0; c < NO_COLS; c++) {
94 short sq = (l * NO_COLS) + c;
96 short n = (short)(v & CNT_MASK);
100 if ( v & ctlP ) strcat(s,"P");
101 if ( v & ctlPp ) strcat(s,"+P");
102 if ( v & ctlL ) strcat(s,"L");
103 if ( v & ctlLp ) strcat(s,"+L");
104 if ( v & ctlN ) strcat(s,"N");
105 if ( v & ctlNp ) strcat(s,"+N");
106 if ( v & ctlS ) strcat(s,"S");
107 if ( v & ctlSp ) strcat(s,"+S");
108 if ( v & ctlG ) strcat(s,"G");
109 if ( v & ctlB ) strcat(s,"B");
110 if ( v & ctlBp ) strcat(s,"+B");
111 if ( v & ctlR ) strcat(s,"R");
112 if ( v & ctlRp ) strcat(s,"+R");
113 if ( v & ctlK ) strcat(s,"K");
115 for (i = strlen(s); i < 5; i++)
127 #define CHECK_DISTANCE
131 SqAtakd (short int square, short int side, short int *blockable)
134 * See if any piece with color 'side' ataks sq.
135 * *blockable == attack could be blocked by drop
142 register unsigned char *ppos, *pdir;
144 register short u, ptyp;
146 if ( MatchSignature(threats_signature[side]) ) {
149 long int a[NO_SQUARES];
151 for ( i = 0, n = -1; i < NO_SQUARES; i++ )
152 if (a[i] != atak[side][i]) {
153 n = i; printf("atak #check error on square %d\n",i);
156 debug_ataks (stdout, a);
157 debug_ataks (stdout, atak[side]);
158 debug_position (stdout);
159 printf("%d pieces\n",PieceCnt[side]);
160 for ( i = PieceCnt[side]; i>= 0; i-- ) {
162 sq = PieceList[side][i];
164 printf("square %d is %d with piece %d\n", i, sq, piece);
166 printf("hashkey = %ld hashbd = %ld\n",hashkey,hashbd);
167 assert(a[n] == atak[side][n]);
171 printf("atak array for %s available for SqAtakd!\n",ColorStr[side]);
173 *blockable = true; /* don't know */
174 return(Anyatak(side,square));
178 * First check neigboured squares,
179 * then check Knights.
180 * then check Bishops,
186 /* try a capture from direct neighboured squares */
188 ptyp = ptype[black][king];
190 u = first_direction(ptyp,&d,square);
192 pdir = (*nextdir[ptyp])[square];
197 if (color[u] == side)
198 /* can piece reach square in one step ? */
199 #ifdef CHECK_DISTANCE
200 if ( piece_distance(side,board[u],u,square) == 1 )
205 short ptypv = ptype[side][board[u]];
208 v = first_direction(ptypv,&dv,u);
211 qdir = (*nextdir[ptypv])[u];
219 v = next_direction(ptypv,&dv,u);
227 u = next_direction(ptyp,&d,square);
231 } while (u != square);
233 /* try a knight capture (using xside's knight moves) */
235 ptyp = ptype[side ^ 1][knight];
237 u = first_direction(ptyp,&d,square);
239 pdir = (*nextdir[ptyp])[square];
244 if (color[u] == side && board[u] == knight)
247 u = next_direction(ptyp,&d,square);
251 } while (u != square);
255 /* try a (promoted) bishop capture */
257 ptyp = ptype[black][bishop];
259 u = first_direction(ptyp,&d,square);
261 ppos = (*nextpos[ptyp])[square];
262 pdir = (*nextdir[ptyp])[square];
267 if (color[u] == neutral)
269 u = next_position(ptyp,&d,square,u);
275 if (color[u] == side && (unpromoted[board[u]] == bishop))
278 u = next_direction(ptyp,&d,square);
283 } while (u != square);
285 /* try a (promoted) rook capture */
287 ptyp = ptype[black][rook];
289 u = first_direction(ptyp,&d,square);
291 ppos = (*nextpos[ptyp])[square];
292 pdir = (*nextdir[ptyp])[square];
297 if (color[u] == neutral)
299 u = next_position(ptyp,&d,square,u);
305 if (color[u] == side && (unpromoted[board[u]] == rook))
308 u = next_direction(ptyp,&d,square);
313 } while (u != square);
315 /* try a lance capture (using xside's lance moves) */
317 ptyp = ptype[side ^ 1][lance];
319 u = first_direction(ptyp,&d,square);
321 ppos = (*nextpos[ptyp])[square];
326 if (color[u] == neutral)
328 u = next_position(ptyp,&d,square,u);
334 if (color[u] == side && (board[u] == lance))
338 } while (u != square);