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);