Bool transition: do not scanf directly into would-be bools.
[gnushogi.git] / gnushogi / attacks.c
blob00a1dcd57d223cd370d77a73968e26adba04ae7f
1 /*
2 * FILE: attacks.c
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
9 * GNU SHOGI is based on GNU CHESS
11 * Copyright (c) 1988, 1989, 1990 John Stanback
12 * Copyright (c) 1992 Free Software Foundation
14 * This file is part of GNU SHOGI.
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.
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.
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 * ----------------------------------------------------------------------
33 #include "gnushogi.h"
36 #define CHECK_DISTANCE
39 * See if any piece with color 'side' attacks sq.
40 * *blockable == attack could be blocked by drop
43 bool
44 SqAttacked(short square, short side, bool *blockable)
46 #ifdef SAVE_NEXTPOS
47 short d;
48 #else
49 unsigned char *ppos, *pdir;
50 #endif
52 short u, ptyp;
54 if (MatchSignature(threats_signature[side]))
56 *blockable = true; /* don't know */
57 return Anyattack(side, square);
61 * First check neighbouring squares,
62 * then check Knights.
63 * then check Bishops,
64 * then (last) check Rooks,
67 *blockable = false;
69 /* try a capture from direct neighboured squares */
71 ptyp = ptype[black][king];
73 #ifdef SAVE_NEXTPOS
74 u = first_direction(ptyp, &d, square);
75 #else
76 pdir = (*nextdir[ptyp])[square];
77 u = pdir[square];
78 #endif
82 if (color[u] == side) /* can piece reach square in one step ? */
83 #ifdef CHECK_DISTANCE
85 if (piece_distance(side, board[u], u, square) == 1)
86 return true;
88 #else
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
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
110 while (v != u);
112 #endif
114 #ifdef SAVE_NEXTPOS
115 u = next_direction(ptyp, &d, square);
116 #else
117 u = pdir[u];
118 #endif
120 while (u != square);
122 #ifndef MINISHOGI
123 /* try a knight capture (using xside's knight moves) */
125 ptyp = ptype[side ^ 1][knight];
127 #ifdef SAVE_NEXTPOS
128 u = first_direction(ptyp, &d, square);
129 #else
130 pdir = (*nextdir[ptyp])[square];
131 u = pdir[square];
132 #endif
136 if (color[u] == side && board[u] == knight)
137 return true;
139 #ifdef SAVE_NEXTPOS
140 u = next_direction(ptyp, &d, square);
141 #else
142 u = pdir[u];
143 #endif
145 while (u != square);
146 #endif /* MINISHOGI */
148 *blockable = true;
150 /* try a (promoted) bishop capture */
152 ptyp = ptype[black][bishop];
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
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
172 if (color[u] == side && (unpromoted[board[u]] == bishop))
173 return true;
175 #ifdef SAVE_NEXTPOS
176 u = next_direction(ptyp, &d, square);
177 #else
178 u = pdir[u];
179 #endif
182 while (u != square);
184 /* try a (promoted) rook capture */
186 ptyp = ptype[black][rook];
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
198 if (color[u] == neutral)
199 #ifdef SAVE_NEXTPOS
201 u = next_position(ptyp, &d, square, u);
203 #else
205 u = ppos[u];
207 #endif
208 else
210 if (color[u] == side && (unpromoted[board[u]] == rook))
211 return true;
213 #ifdef SAVE_NEXTPOS
214 u = next_direction(ptyp, &d, square);
215 #else
216 u = pdir[u];
217 #endif
220 while (u != square);
222 #ifndef MINISHOGI
223 /* try a lance capture (using xside's lance moves) */
225 ptyp = ptype[side ^ 1][lance];
227 #ifdef SAVE_NEXTPOS
228 u = first_direction(ptyp, &d, square);
229 #else
230 ppos = (*nextpos[ptyp])[square];
231 u = ppos[square];
232 #endif
236 if (color[u] == neutral)
237 #ifdef SAVE_NEXTPOS
239 u = next_position(ptyp, &d, square, u);
241 #else
243 u = ppos[u];
245 #endif
246 else
248 if ((color[u] == side) && (board[u] == lance))
249 return true;
251 u = square;
254 while (u != square);
255 #endif /* MINISHOGI */
257 return false;