1 #include "chess.h"
2 #include "data.h"
3 /* last modified 01/07/14 */
4 /*
5 *******************************************************************************
6 * *
7 * Attacks() is used to determine if <side> attacks <square>. The algorithm *
8 * is simple, and is based on the AttacksTo() algorithm, but, rather than *
9 * returning a bitmap of squares attacking <square> it returns a "1" as soon *
10 * as it finds anything that attacks <square>. *
11 * *
12 *******************************************************************************
13 */
Attacks(TREE * RESTRICT tree,int side,int square)14 int Attacks(TREE * RESTRICT tree, int side, int square) {
15 if ((rook_attacks[square] & (Rooks(side) | Queens(side)))
16 && (RookAttacks(square,
17 OccupiedSquares) & (Rooks(side) | Queens(side))))
18 return 1;
19 if ((bishop_attacks[square] & (Bishops(side) | Queens(side)))
20 && (BishopAttacks(square,
21 OccupiedSquares) & (Bishops(side) | Queens(side))))
22 return 1;
23 if (KnightAttacks(square) & Knights(side))
24 return 1;
25 if (PawnAttacks(Flip(side), square) & Pawns(side))
26 return 1;
27 if (KingAttacks(square) & Kings(side))
28 return 1;
29 return 0;
30 }
31
32 /* last modified 01/07/14 */
33 /*
34 *******************************************************************************
35 * *
36 * AttacksTo() is used to produce a bitboard which is a map of all squares *
37 * that directly attack this <square>. The non-sliding pieces are trivial *
38 * to detect, but for sliding pieces, we use a bitboard trick. The idea is *
39 * to compute the squares a queen would attack, if it was standing on *
40 * <square> and then look at the last square attacked in each direction to *
41 * determine if it is a sliding piece that moves in the right direction. To *
42 * finish up, we simply need to Or() all these attackers together. *
43 * *
44 *******************************************************************************
45 */
AttacksTo(TREE * RESTRICT tree,int square)46 uint64_t AttacksTo(TREE * RESTRICT tree, int square) {
47 uint64_t attacks =
48 (PawnAttacks(white, square) & Pawns(black)) | (PawnAttacks(black,
49 square) & Pawns(white));
50 uint64_t bsliders =
51 Bishops(white) | Bishops(black) | Queens(white) | Queens(black);
52 uint64_t rsliders =
53 Rooks(white) | Rooks(black) | Queens(white) | Queens(black);
54 attacks |= KnightAttacks(square) & (Knights(black) | Knights(white));
55 if (bishop_attacks[square] & bsliders)
56 attacks |= BishopAttacks(square, OccupiedSquares) & bsliders;
57 if (rook_attacks[square] & rsliders)
58 attacks |= RookAttacks(square, OccupiedSquares) & rsliders;
59 attacks |= KingAttacks(square) & (Kings(black) | Kings(white));
60 return attacks;
61 }
62
63 /* last modified 01/07/14 */
64 /*
65 *******************************************************************************
66 * *
67 * AttacksFrom() is used to compute the set of squares the piece on <source> *
68 * attacks. *
69 * *
70 *******************************************************************************
71 */
AttacksFrom(TREE * RESTRICT tree,int side,int source)72 uint64_t AttacksFrom(TREE * RESTRICT tree, int side, int source) {
73
74 switch (Abs(PcOnSq(source))) {
75 case queen:
76 return QueenAttacks(source, OccupiedSquares);
77 case rook:
78 return RookAttacks(source, OccupiedSquares);
79 case bishop:
80 return BishopAttacks(source, OccupiedSquares);
81 case knight:
82 return KnightAttacks(source);
83 case pawn:
84 return PawnAttacks(side, source);
85 case king:
86 return KingAttacks(source);
87 }
88 return 0;
89 }
90
91 /* last modified 01/07/14 */
92 /*
93 *******************************************************************************
94 * *
95 * Attacked() is used to determine if <square> is attacked. It returns a *
96 * two bit value, 01 if <square> is attacked by <side>, 10 if <square> is *
97 * attacked by <enemy> and 11 if <square> is attacked by both sides. *
98 * *
99 *******************************************************************************
100 */
Attacked(TREE * RESTRICT tree,int side,uint64_t squares)101 uint64_t Attacked(TREE * RESTRICT tree, int side, uint64_t squares) {
102 uint64_t bsliders, rsliders, set;
103 int square;
104
105 bsliders = Bishops(side) | Queens(side);
106 rsliders = Rooks(side) | Queens(side);
107 for (set = squares; set; set &= set - 1) {
108 square = LSB(set);
109 do {
110 if (KingAttacks(square) & Kings(side))
111 break;
112 if (KnightAttacks(square) & Knights(side))
113 break;
114 if (bishop_attacks[square] & bsliders &&
115 BishopAttacks(square, OccupiedSquares) & bsliders)
116 break;
117 if (rook_attacks[square] & rsliders &&
118 RookAttacks(square, OccupiedSquares) & rsliders)
119 break;
120 Clear(square, squares);
121 } while (0);
122 }
123 return squares;
124 }
125