2 /* This file contains code for X-CHESS.
3 Copyright (C) 1986 Free Software Foundation, Inc.
5 This file is part of X-CHESS.
7 X-CHESS is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY. No author or distributor
9 accepts responsibility to anyone for the consequences of using it
10 or for whether it serves any particular purpose or works at all,
11 unless he says so in writing. Refer to the X-CHESS General Public
12 License for full details.
14 Everyone is granted permission to copy, modify and redistribute
15 X-CHESS, but only under the conditions described in the
16 X-CHESS General Public License. A copy of this license is
17 supposed to have been given to you along with X-CHESS so you
18 can know your rights and responsibilities. It should be in a
19 file named COPYING. Among other things, the copyright notice
20 and this notice must be preserved on all copies. */
23 /* RCS Info: $Revision: 1.3 $ on $Date: 86/11/23 17:18:35 $
24 * $Source: /users/faustus/xchess/RCS/valid.c,v $
25 * Copyright (c) 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
26 * Permission is granted to do anything with this code except sell it
27 * or remove this message.
34 extern bool ischeck(), couldmove();
43 /* First check that the piece can make the move at all... */
47 /* Now see if the king is in check now. */
48 bcopy((char *) b, (char *) &tb, sizeof (board));
50 if (ischeck(&tb, m->piece.color))
53 if (ischeck(&tb, ((m->piece.color == WHITE) ? BLACK : WHITE)))
68 if ((m->piece.color == WHITE) && (b->white_cant_castle_k) ||
69 (m->piece.color == BLACK) &&
70 (b->black_cant_castle_k))
72 if ((b->square[m->fromy][5].color != NONE) ||
73 (b->square[m->fromy][6].color != NONE))
75 if (ischeck(b, m->piece.color))
80 if ((m->piece.color == WHITE) && (b->white_cant_castle_q) ||
81 (m->piece.color == BLACK) &&
82 (b->black_cant_castle_q))
84 if ((b->square[m->fromy][1].color != NONE) ||
85 (b->square[m->fromy][2].color != NONE) ||
86 (b->square[m->fromy][3].color != NONE))
88 if (ischeck(b, m->piece.color))
94 /* There is one special case here, that of taking a pawn
95 * en passant. In this case we change the move field to
98 switch (m->piece.type) {
100 if ((m->type == MOVE) && (m->fromx == m->tox)) {
102 if ((m->piece.color == WHITE) && (m->fromy ==
105 if ((m->piece.color == WHITE) && (m->fromy ==
106 6) && (m->toy == 4) &&
107 (b->square[5][m->fromx].color
110 if ((m->piece.color == BLACK) && (m->fromy ==
113 if ((m->piece.color == BLACK) && (m->fromy ==
114 1) && (m->toy == 3) &&
115 (b->square[2][m->fromx].color
119 } else if (m->type == CAPTURE) {
120 if ((((m->piece.color == WHITE) && (m->fromy ==
121 m->toy + 1)) || ((m->piece.color ==
122 BLACK) && (m->fromy == m->toy -
123 1))) && ((m->fromx == m->tox + 1) ||
124 (m->fromx == m->tox - 1)))
126 /* Now maybe it's enpassant... We've already
127 * checked for some of these things in the
131 if (b->square[(m->piece.color == WHITE)
132 ? 3 : 4][m->tox].color ==
133 ((m->piece.color == WHITE) ?
142 if (m->fromx == m->tox) {
143 for (y = m->fromy + ((m->fromy > m->toy) ? -1 :
144 1); y != m->toy; y += ((m->fromy
146 if (b->square[y][m->tox].color != NONE)
150 if (m->fromy == m->toy) {
151 for (x = m->fromx + ((m->fromx > m->tox) ? -1 :
152 1); x != m->tox; x += ((m->fromx
154 if (b->square[m->toy][x].color != NONE)
161 x = m->fromx - m->tox;
162 y = m->fromy - m->toy;
163 if ((((x == 2) || (x == -2)) &&
164 ((y == 1) || (y == -1))) ||
165 (((x == 1) || (x == -1)) &&
166 ((y == 2) || (y == -2))))
171 x = m->fromx - m->tox;
172 y = m->fromy - m->toy;
173 if ((x != y) && (x != - y))
175 for (x = m->fromx + ((m->fromx > m->tox) ? -1 : 1), y =
176 m->fromy + ((m->fromy > m->toy) ? -1 :
178 x += ((m->fromx > m->tox) ? -1 : 1),
179 y += ((m->fromy > m->toy) ? -1 : 1))
180 if (b->square[y][x].color != NONE)
185 if (m->fromx == m->tox) {
186 for (y = m->fromy + ((m->fromy > m->toy) ? -1 :
187 1); y != m->toy; y += ((m->fromy
189 if (b->square[y][m->tox].color != NONE)
193 if (m->fromy == m->toy) {
194 for (x = m->fromx + ((m->fromx > m->tox) ? -1 :
195 1); x != m->tox; x += ((m->fromx
197 if (b->square[m->toy][x].color != NONE)
201 x = m->fromx - m->tox;
202 y = m->fromy - m->toy;
203 if ((x != y) && (x != - y))
205 for (x = m->fromx + ((m->fromx > m->tox) ? -1 : 1), y =
206 m->fromy + ((m->fromy > m->toy) ? -1 :
208 x += ((m->fromx > m->tox) ? -1 : 1),
209 y += ((m->fromy > m->toy) ? -1 : 1))
210 if (b->square[y][x].color != NONE)
215 x = m->fromx - m->tox;
216 y = m->fromy - m->toy;
217 if ((x >= -1) && (x <= 1) && (y >= -1) && (y <= 1))
226 /* Say whether either king is in check... If move is non-NULL, say whether he
227 * in in check after the move takes place. We do this in a rather stupid way.
238 for (x = 0; x < SIZE; x++)
239 for (y = 0; y < SIZE; y++)
240 if ((b->square[y][x].color == col) &&
241 (b->square[y][x].type == KING)) {
246 for (x = 0; x < SIZE; x++)
247 for (y = 0; y < SIZE; y++)
248 if (b->square[y][x].color == ((col == WHITE) ?
251 ch.piece.color = b->square[y][x].color;
252 ch.piece.type = b->square[y][x].type;
257 ch.enpassant = false;
258 if (couldmove(&ch, b))