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