1 /* atak.c
2
3 GNU Chess frontend
4
5 Copyright (C) 2001-2011 Free Software Foundation, Inc.
6
7 GNU Chess is based on the two research programs
8 Cobalt by Chua Kong-Sian and Gazebo by Stuart Cracraft.
9
10 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22
23 Contact Info:
24 bug-gnu-chess@gnu.org
25 cracraft@ai.mit.edu, cracraft@stanfordalumni.org, cracraft@earthlink.net
26 */
27
28 #include <stdio.h>
29 #include <string.h>
30 #include "common.h"
31
32
SqAtakd(short sq,short side)33 short SqAtakd (short sq, short side)
34 /**************************************************************************
35 *
36 * To determine if sq is attacked by any pieces from side.
37 *
38 **************************************************************************/
39 {
40 register BitBoard *a, b, *c, d, blocker;
41 int t;
42
43 a = board.b[side];
44
45 /* Knights */
46 if (a[knight] & MoveArray[knight][sq])
47 return (true);
48
49 /* Kings */
50 if (a[king] & MoveArray[king][sq])
51 return (true);
52
53 /* Pawns */
54 if (a[pawn] & MoveArray[ptype[1^side]][sq])
55 return (true);
56
57 c = FromToRay[sq];
58 blocker = board.blocker;
59
60 /* Bishops & Queen */
61 b = (a[bishop] | a[queen]) & MoveArray[bishop][sq];
62 d = ~b & blocker;
63 while (b)
64 {
65 t = leadz (b);
66 if (!(c[t] & d))
67 return (true);
68 CLEARBIT (b, t);
69 }
70
71 /* Rooks & Queen */
72 b = (a[rook] | a[queen]) & MoveArray[rook][sq];
73 d = ~b & blocker;
74 while (b)
75 {
76 t = leadz (b);
77 if (!(c[t] & d))
78 return (true);
79 CLEARBIT (b, t);
80 }
81 return (false);
82 }
83
AttackTo(int sq,int side)84 BitBoard AttackTo (int sq, int side)
85 /***************************************************************************
86 *
87 * Generate a bitboard of all squares with pieces belonging to side
88 * which attack sq.
89 *
90 ***************************************************************************/
91 {
92 register BitBoard *a, b, *c, e, blocker;
93 int t;
94
95 a = board.b[side];
96
97 /* Knights */
98 e = (a[knight] & MoveArray[knight][sq]);
99
100 /* Kings */
101 e |= (a[king] & MoveArray[king][sq]);
102
103 /* Pawns */
104 e |= (a[pawn] & MoveArray[ptype[1^side]][sq]);
105
106 c = FromToRay[sq];
107 blocker = board.blocker;
108
109 /* Bishops & Queen */
110 b = (a[bishop] | a[queen]) & MoveArray[bishop][sq];
111 while (b)
112 {
113 t = leadz (b);
114 CLEARBIT (b, t);
115 if (!(c[t] & blocker & NotBitPosArray[t]))
116 e |= BitPosArray[t];
117 }
118
119 /* Rooks & Queen */
120 b = (a[rook] | a[queen]) & MoveArray[rook][sq];
121 while (b)
122 {
123 t = leadz (b);
124 CLEARBIT (b, t);
125 if (!(c[t] & blocker & NotBitPosArray[t]))
126 e |= BitPosArray[t];
127 }
128
129 return (e);
130 }
131
132
PinnedOnKing(int sq,int side)133 int PinnedOnKing (int sq, int side)
134 /***************************************************************************
135 *
136 * Determine if the piece on sq is pinned against the King.
137 * Side is the color of the piece.
138 * Caveat: PinnedOnKing should only be called by GenCheckEscapes().
139 * The more generic FindPins() function should be used for evaluating
140 * pins against other pieces.
141 *
142 ***************************************************************************/
143 {
144 int xside;
145 int KingSq, dir, sq1;
146 BitBoard b, blocker;
147
148 KingSq = board.king[side];
149 if ((dir = directions[KingSq][sq]) == -1)
150 return (false);
151
152 xside = 1 ^ side;
153 blocker = board.blocker;
154
155 /* Path from piece to king is blocked, so no pin */
156 if (FromToRay[KingSq][sq] & NotBitPosArray[sq] & blocker)
157 return (false);
158 b = (Ray[KingSq][dir] ^ FromToRay[KingSq][sq]) & blocker;
159 if (b == NULLBITBOARD)
160 return (false);
161 sq1 = (sq > KingSq ? leadz (b) : trailz (b));
162
163 /* If diagonal */
164 if (dir <= 3 &&
165 BitPosArray[sq1] & (board.b[xside][queen] | board.b[xside][bishop]))
166 return (true);
167
168 /* Rank / file */
169 if (dir >= 4 &&
170 BitPosArray[sq1] & (board.b[xside][queen] | board.b[xside][rook]))
171 return (true);
172
173 return (false);
174 }
175
176