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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
#define MOVES_INTERNAL
#include "engine/moves.h"
static bool pawn_attacks_square(position_t position, square_t square, u8 by_color) {
bitboard_t enemy_pawns;
if (by_color == WHITE_TURN) {
enemy_pawns = position.bitboards[WHITE_PAWN];
if (square < 8) return false;
bitboard_t nw = (square % 8 == 7) ? 0 : (enemy_pawns >> (square - 7));
bitboard_t ne = (square % 8 == 0) ? 0 : (enemy_pawns >> (square - 9));
return (nw | ne) & 1;
} else {
enemy_pawns = position.bitboards[BLACK_PAWN];
if (square > 54) return false;
bitboard_t se = (square % 8 == 0) ? 0 : (enemy_pawns >> (square + 7));
bitboard_t sw = (square % 8 == 7) ? 0 : (enemy_pawns >> (square + 9));
return (se | sw) & 1;
}
}
static bool knight_attacks_square(position_t position, square_t square, u8 by_color) {
bitboard_t enemy_knights = (by_color == WHITE_TURN)
? position.bitboards[WHITE_KNIGHT]
: position.bitboards[BLACK_KNIGHT];
return knight_moves[square] & enemy_knights;
}
static bool king_attacks_square(position_t position, square_t square, u8 by_color) {
bitboard_t enemy_king = (by_color == WHITE_TURN)
? position.bitboards[WHITE_KING]
: position.bitboards[BLACK_KING];
bitboard_t movement;
if (square >= 10) {
movement = 920078ULL << (square - 10);
} else {
movement = 920078ULL >> -(square - 10);
}
if ((bitboard_t)1 << square & BITMASK_FILE_A) {
movement &= BITMASK_FILE_A | BITMASK_FILE_B;
} else if ((bitboard_t)1 << square & BITMASK_FILE_H) {
movement &= BITMASK_FILE_G | BITMASK_FILE_H;
}
return movement & enemy_king;
}
static bool sliding_attacks_square(
position_t position,
square_t square,
u8 by_color,
bool check_rook,
bool check_bishop
) {
bitboard_t all_occupied = whites(position) | blacks(position);
int rank = square / 8;
int file = square % 8;
bitboard_t enemy_rooks = (by_color == WHITE_TURN) ? position.bitboards[WHITE_ROOK] : position.bitboards[BLACK_ROOK];
bitboard_t enemy_bishops = (by_color == WHITE_TURN) ? position.bitboards[WHITE_BISHOP] : position.bitboards[BLACK_BISHOP];
bitboard_t enemy_queens = (by_color == WHITE_TURN) ? position.bitboards[WHITE_QUEEN] : position.bitboards[BLACK_QUEEN];
if (check_rook) {
bitboard_t rook_like = enemy_rooks | enemy_queens;
int r, idx;
r = rank + 1;
while (r < 8) {
idx = r * 8 + file;
if ((all_occupied >> idx) & 1) {
if ((rook_like >> idx) & 1) return true;
break;
}
r++;
}
r = rank - 1;
while (r >= 0) {
idx = r * 8 + file;
if ((all_occupied >> idx) & 1) {
if ((rook_like >> idx) & 1) return true;
break;
}
r--;
}
int f = file + 1;
while (f < 8) {
idx = rank * 8 + f;
if ((all_occupied >> idx) & 1) {
if ((rook_like >> idx) & 1) return true;
break;
}
f++;
}
f = file - 1;
while (f >= 0) {
idx = rank * 8 + f;
if ((all_occupied >> idx) & 1) {
if ((rook_like >> idx) & 1) return true;
break;
}
f--;
}
}
if (check_bishop) {
bitboard_t bishop_like = enemy_bishops | enemy_queens;
int r, f, idx;
r = rank + 1; f = file + 1;
while (r < 8 && f < 8) {
idx = r * 8 + f;
if ((all_occupied >> idx) & 1) {
if ((bishop_like >> idx) & 1) return true;
break;
}
r++; f++;
}
r = rank - 1; f = file - 1;
while (r >= 0 && f >= 0) {
idx = r * 8 + f;
if ((all_occupied >> idx) & 1) {
if ((bishop_like >> idx) & 1) return true;
break;
}
r--; f--;
}
r = rank - 1; f = file + 1;
while (r >= 0 && f < 8) {
idx = r * 8 + f;
if ((all_occupied >> idx) & 1) {
if ((bishop_like >> idx) & 1) return true;
break;
}
r--; f++;
}
r = rank + 1; f = file - 1;
while (r < 8 && f >= 0) {
idx = r * 8 + f;
if ((all_occupied >> idx) & 1) {
if ((bishop_like >> idx) & 1) return true;
break;
}
r++; f--;
}
}
return false;
}
bool square_attacked(position_t position, square_t square, u8 by_color) {
if (pawn_attacks_square(position, square, by_color)) return true;
if (knight_attacks_square(position, square, by_color)) return true;
if (king_attacks_square(position, square, by_color)) return true;
if (sliding_attacks_square(position, square, by_color, true, true)) return true;
return false;
}
|