1 /*
2 * FILE: attacks.c
3 *
4 * ----------------------------------------------------------------------
5 * Copyright (c) 1993, 1994, 1995 Matthias Mutz
6 * Copyright (c) 1999 Michael Vanier and the Free Software Foundation
7 * Copyright (c) 2008, 2013, 2014 Yann Dirson and the Free Software Foundation
8 *
9 * GNU SHOGI is based on GNU CHESS
10 *
11 * Copyright (c) 1988, 1989, 1990 John Stanback
12 * Copyright (c) 1992 Free Software Foundation
13 *
14 * This file is part of GNU SHOGI.
15 *
16 * GNU Shogi is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License as published by the
18 * Free Software Foundation; either version 3 of the License,
19 * or (at your option) any later version.
20 *
21 * GNU Shogi is distributed in the hope that it will be useful, but WITHOUT
22 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 * for more details.
25 *
26 * You should have received a copy of the GNU General Public License along
27 * with GNU Shogi; see the file COPYING. If not, see
28 * <http://www.gnu.org/licenses/>.
29 * ----------------------------------------------------------------------
30 *
31 */
32
33 #include "gnushogi.h"
34
35
36 #define CHECK_DISTANCE
37
38 /*
39 * See if any piece with color 'side' attacks sq.
40 * *blockable == attack could be blocked by drop
41 */
42
43 int
SqAttacked(short square,short side,short * blockable)44 SqAttacked(short square, short side, short *blockable)
45 {
46 #ifdef SAVE_NEXTPOS
47 short d;
48 #else
49 unsigned char *ppos, *pdir;
50 #endif
51
52 short u, ptyp;
53
54 if (MatchSignature(threats_signature[side]))
55 {
56 *blockable = true; /* don't know */
57 return Anyattack(side, square);
58 }
59
60 /*
61 * First check neighbouring squares,
62 * then check Knights.
63 * then check Bishops,
64 * then (last) check Rooks,
65 */
66
67 *blockable = false;
68
69 /* try a capture from direct neighboured squares */
70
71 ptyp = ptype[black][king];
72
73 #ifdef SAVE_NEXTPOS
74 u = first_direction(ptyp, &d, square);
75 #else
76 pdir = (*nextdir[ptyp])[square];
77 u = pdir[square];
78 #endif
79
80 do
81 {
82 if (color[u] == side) /* can piece reach square in one step ? */
83 #ifdef CHECK_DISTANCE
84 {
85 if (piece_distance(side, board[u], u, square) == 1)
86 return true;
87 }
88 #else
89 {
90 short v;
91 short ptypv = ptype[side][board[u]];
92 #ifdef SAVE_NEXTPOS
93 short dv;
94 v = first_direction(ptypv, &dv, u);
95 #else
96 unsigned char *qdir;
97 qdir = (*nextdir[ptypv])[u];
98 v = qdir[u];
99 #endif
100 do
101 {
102 if (v == square)
103 return true;
104 #ifdef SAVE_NEXTPOS
105 v = next_direction(ptypv, &dv, u);
106 #else
107 v = qdir[v];
108 #endif
109 }
110 while (v != u);
111 }
112 #endif
113
114 #ifdef SAVE_NEXTPOS
115 u = next_direction(ptyp, &d, square);
116 #else
117 u = pdir[u];
118 #endif
119 }
120 while (u != square);
121
122 #ifndef MINISHOGI
123 /* try a knight capture (using xside's knight moves) */
124
125 ptyp = ptype[side ^ 1][knight];
126
127 #ifdef SAVE_NEXTPOS
128 u = first_direction(ptyp, &d, square);
129 #else
130 pdir = (*nextdir[ptyp])[square];
131 u = pdir[square];
132 #endif
133
134 do
135 {
136 if (color[u] == side && board[u] == knight)
137 return true;
138
139 #ifdef SAVE_NEXTPOS
140 u = next_direction(ptyp, &d, square);
141 #else
142 u = pdir[u];
143 #endif
144 }
145 while (u != square);
146 #endif /* MINISHOGI */
147
148 *blockable = true;
149
150 /* try a (promoted) bishop capture */
151
152 ptyp = ptype[black][bishop];
153
154 #ifdef SAVE_NEXTPOS
155 u = first_direction(ptyp, &d, square);
156 #else
157 ppos = (*nextpos[ptyp])[square];
158 pdir = (*nextdir[ptyp])[square];
159 u = ppos[square];
160 #endif
161
162 do
163 {
164 if (color[u] == neutral)
165 #ifdef SAVE_NEXTPOS
166 u = next_position(ptyp, &d, square, u);
167 #else
168 u = ppos[u];
169 #endif
170 else
171 {
172 if (color[u] == side && (unpromoted[board[u]] == bishop))
173 return true;
174
175 #ifdef SAVE_NEXTPOS
176 u = next_direction(ptyp, &d, square);
177 #else
178 u = pdir[u];
179 #endif
180 }
181 }
182 while (u != square);
183
184 /* try a (promoted) rook capture */
185
186 ptyp = ptype[black][rook];
187
188 #ifdef SAVE_NEXTPOS
189 u = first_direction(ptyp, &d, square);
190 #else
191 ppos = (*nextpos[ptyp])[square];
192 pdir = (*nextdir[ptyp])[square];
193 u = ppos[square];
194 #endif
195
196 do
197 {
198 if (color[u] == neutral)
199 #ifdef SAVE_NEXTPOS
200 {
201 u = next_position(ptyp, &d, square, u);
202 }
203 #else
204 {
205 u = ppos[u];
206 }
207 #endif
208 else
209 {
210 if (color[u] == side && (unpromoted[board[u]] == rook))
211 return true;
212
213 #ifdef SAVE_NEXTPOS
214 u = next_direction(ptyp, &d, square);
215 #else
216 u = pdir[u];
217 #endif
218 }
219 }
220 while (u != square);
221
222 #ifndef MINISHOGI
223 /* try a lance capture (using xside's lance moves) */
224
225 ptyp = ptype[side ^ 1][lance];
226
227 #ifdef SAVE_NEXTPOS
228 u = first_direction(ptyp, &d, square);
229 #else
230 ppos = (*nextpos[ptyp])[square];
231 u = ppos[square];
232 #endif
233
234 do
235 {
236 if (color[u] == neutral)
237 #ifdef SAVE_NEXTPOS
238 {
239 u = next_position(ptyp, &d, square, u);
240 }
241 #else
242 {
243 u = ppos[u];
244 }
245 #endif
246 else
247 {
248 if ((color[u] == side) && (board[u] == lance))
249 return true;
250
251 u = square;
252 }
253 }
254 while (u != square);
255 #endif /* MINISHOGI */
256
257 return false;
258 }
259
260