GNU Shogi 1.2p03
[gnushogi.git] / src / ataks.c
blob0f87dac9a153d9181ed0c523d50ea673804d372f
1 /*
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.
26 #include "gnushogi.h"
28 #ifdef DEBUG
29 #include <assert.h>
30 #endif
33 #if defined DEBUG
35 void
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.
41 */
44 register short u, sq;
45 long int c;
46 #ifdef SAVE_NEXTPOS
47 short d;
48 #else
49 register unsigned char *ppos, *pdir;
50 #endif
51 short i, piece;
52 small_short *PL;
54 array_zero (a, NO_SQUARES * sizeof (a[0]));
56 PL = PieceList[side];
57 for (i = PieceCnt[side]; i >= 0; i--)
58 { short ptyp;
59 sq = PL[i];
60 piece = board[sq];
61 ptyp = ptype[side][piece];
62 c = control[piece];
63 #ifdef SAVE_NEXTPOS
64 u = first_direction(ptyp,&d,sq);
65 #else
66 ppos = (*nextpos[ptyp])[sq];
67 pdir = (*nextdir[ptyp])[sq];
68 u = ppos[sq];
69 #endif
70 do {
71 a[u] = ((a[u]+1) | c);
72 #ifdef SAVE_NEXTPOS
73 u = ((color[u] == neutral) ? next_position(ptyp,&d,sq,u)
74 : next_direction(ptyp,&d,sq));
75 #else
76 u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
77 #endif
78 } while (u != sq);
82 #endif
85 #if defined DEBUG || defined DEBUG_EVAL
87 void
88 debug_ataks (FILE *D, long *atk)
90 short l,c,i;
91 fprintf(D, "\n");
92 for (l = NO_ROWS-1; l >= 0; l--) {
93 for (c = 0; c < NO_COLS; c++) {
94 short sq = (l * NO_COLS) + c;
95 long v = atk[sq];
96 short n = (short)(v & CNT_MASK);
97 char s[20];
98 fprintf(D,"%2d",n);
99 strcpy(s,"");
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");
114 fprintf(D,s);
115 for (i = strlen(s); i < 5; i++)
116 fprintf(D," ");
117 fprintf(D," ");
119 fprintf(D,"\n");
121 fprintf(D, "\n");
124 #endif
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
139 #ifdef SAVE_NEXTPOS
140 short d;
141 #else
142 register unsigned char *ppos, *pdir;
143 #endif
144 register short u, ptyp;
146 if ( MatchSignature(threats_signature[side]) ) {
147 #ifdef DEBUG
148 short i,n, sq;
149 long int a[NO_SQUARES];
150 ataks(side,a);
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);
155 if ( n >= 0 ) {
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-- ) {
161 short sq, piece;
162 sq = PieceList[side][i];
163 piece = board[sq];
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]);
169 #endif
170 #ifdef notdef
171 printf("atak array for %s available for SqAtakd!\n",ColorStr[side]);
172 #endif
173 *blockable = true; /* don't know */
174 return(Anyatak(side,square));
178 * First check neigboured squares,
179 * then check Knights.
180 * then check Bishops,
181 * last check Rooks,
184 *blockable = false;
186 /* try a capture from direct neighboured squares */
188 ptyp = ptype[black][king];
189 #ifdef SAVE_NEXTPOS
190 u = first_direction(ptyp,&d,square);
191 #else
192 pdir = (*nextdir[ptyp])[square];
193 u = pdir[square];
194 #endif
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 )
201 return(true);
202 #else
204 short v;
205 short ptypv = ptype[side][board[u]];
206 #ifdef SAVE_NEXTPOS
207 short dv;
208 v = first_direction(ptypv,&dv,u);
209 #else
210 unsigned char *qdir;
211 qdir = (*nextdir[ptypv])[u];
212 v = qdir[u];
213 #endif
216 if (v == square)
217 return (true);
218 #ifdef SAVE_NEXTPOS
219 v = next_direction(ptypv,&dv,u);
220 #else
221 v = qdir[v];
222 #endif
223 } while (v != u);
225 #endif
226 #ifdef SAVE_NEXTPOS
227 u = next_direction(ptyp,&d,square);
228 #else
229 u = pdir[u];
230 #endif
231 } while (u != square);
233 /* try a knight capture (using xside's knight moves) */
235 ptyp = ptype[side ^ 1][knight];
236 #ifdef SAVE_NEXTPOS
237 u = first_direction(ptyp,&d,square);
238 #else
239 pdir = (*nextdir[ptyp])[square];
240 u = pdir[square];
241 #endif
244 if (color[u] == side && board[u] == knight)
245 return (true);
246 #ifdef SAVE_NEXTPOS
247 u = next_direction(ptyp,&d,square);
248 #else
249 u = pdir[u];
250 #endif
251 } while (u != square);
253 *blockable = true;
255 /* try a (promoted) bishop capture */
257 ptyp = ptype[black][bishop];
258 #ifdef SAVE_NEXTPOS
259 u = first_direction(ptyp,&d,square);
260 #else
261 ppos = (*nextpos[ptyp])[square];
262 pdir = (*nextdir[ptyp])[square];
263 u = ppos[square];
264 #endif
267 if (color[u] == neutral)
268 #ifdef SAVE_NEXTPOS
269 u = next_position(ptyp,&d,square,u);
270 #else
271 u = ppos[u];
272 #endif
273 else
275 if (color[u] == side && (unpromoted[board[u]] == bishop))
276 return (true);
277 #ifdef SAVE_NEXTPOS
278 u = next_direction(ptyp,&d,square);
279 #else
280 u = pdir[u];
281 #endif
283 } while (u != square);
285 /* try a (promoted) rook capture */
287 ptyp = ptype[black][rook];
288 #ifdef SAVE_NEXTPOS
289 u = first_direction(ptyp,&d,square);
290 #else
291 ppos = (*nextpos[ptyp])[square];
292 pdir = (*nextdir[ptyp])[square];
293 u = ppos[square];
294 #endif
297 if (color[u] == neutral)
298 #ifdef SAVE_NEXTPOS
299 u = next_position(ptyp,&d,square,u);
300 #else
301 u = ppos[u];
302 #endif
303 else
305 if (color[u] == side && (unpromoted[board[u]] == rook))
306 return (true);
307 #ifdef SAVE_NEXTPOS
308 u = next_direction(ptyp,&d,square);
309 #else
310 u = pdir[u];
311 #endif
313 } while (u != square);
315 /* try a lance capture (using xside's lance moves) */
317 ptyp = ptype[side ^ 1][lance];
318 #ifdef SAVE_NEXTPOS
319 u = first_direction(ptyp,&d,square);
320 #else
321 ppos = (*nextpos[ptyp])[square];
322 u = ppos[square];
323 #endif
326 if (color[u] == neutral)
327 #ifdef SAVE_NEXTPOS
328 u = next_position(ptyp,&d,square,u);
329 #else
330 u = ppos[u];
331 #endif
332 else
334 if (color[u] == side && (board[u] == lance))
335 return (true);
336 u = square;
338 } while (u != square);
340 return (false);