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