Skip to content

Commit 08822de

Browse files
authored
Insane search speed (1.386s for depth 1->8)
1 parent 702549c commit 08822de

File tree

7 files changed

+314
-330
lines changed

7 files changed

+314
-330
lines changed

eval.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ std::unordered_map<U64, int> transposition; // Faster lookup
66
int evaluatePawnStructure(const chess::Board& board);
77
int evaluatePieces(const chess::Board& board);
88

9-
int eval(const chess::Board& board) {
9+
int eval(chess::Board &board) {
1010
U64 hash = board.hash();
11-
1211
// Faster lookup & insertion
1312
auto [it, inserted] = transposition.emplace(hash, 0);
1413
if (!inserted) return it->second; // Already exists, return stored evaluation
@@ -36,13 +35,19 @@ int eval(const chess::Board& board) {
3635
(Bishop * (pieceCount[2] - pieceCount[7])) +
3736
(Rook * (pieceCount[3] - pieceCount[8])) +
3837
(Queen * (pieceCount[4] - pieceCount[9]));
39-
38+
4039
// Evaluate positional aspects
4140
eval += evaluatePawnStructure(board);
4241
eval += evaluatePieces(board);
4342
eval += evaluateKingSafety(board);
4443
eval += evaluateTactics(board);
45-
44+
board.makeNullMove();
45+
// Evaluate positional aspects
46+
eval -= evaluatePawnStructure(board);
47+
eval -= evaluatePieces(board);
48+
eval -= evaluateKingSafety(board);
49+
eval -= evaluateTactics(board);
50+
board.unmakeNullMove();
4651
it->second = eval; // Store result
4752
return eval;
4853
}
@@ -61,3 +66,4 @@ int evaluatePieces(const chess::Board& board) {
6166
return -(evaluateBadBishops(board) + evaluateTrappedPieces(board) + evaluateKnightForks(board)) +
6267
(evaluateFianchetto(board) + evaluateRooksOnFiles(board));
6368
}
69+

eval.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@
1313
#define Queen 900
1414
#define MATE(i) MAX-i
1515
#define MATE_DISTANCE(i) i-MAX_MATE
16-
int eval(const chess::Board&);
16+
int eval(chess::Board&);

main.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
extern unsigned long long nodes;
55
int main(){
66
chess::Board board;
7-
for (int i=2;i<245;++i){
7+
for (int i=1;i<=8;++i){
8+
//Clear transposition
9+
if (!clearTransposition())int x=1/0;//force div/0 err
810
std::cout<<i<<" ";
9-
std::cout<<search(board,i,-MAX,MAX)<<" "<<nodes<<std::endl;
11+
std::cout<<search(board,i,-MAX,MAX,0)<<" "<<nodes<<std::endl;
1012
nodes=0;
1113
}
1214
return 0;

patterns.cpp

Lines changed: 58 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -114,55 +114,85 @@ int evaluateTactics(const chess::Board& board) {
114114
if (tacticsCache.find(hash) != tacticsCache.end()) return tacticsCache[hash];
115115

116116
int score = 0;
117-
118-
chess::Square myKing = board.kingSq(board.sideToMove());
119-
chess::Square enemyKing = board.kingSq(~board.sideToMove());
117+
U64 myPieces = board.us(board.sideToMove()).getBits();
118+
U64 enemyPieces = board.them(board.sideToMove()).getBits();
120119

121120
// **1. Pin Check**
122-
for (chess::Square pieceSq : scan_reversed(board.us(board.sideToMove()).getBits())) {
123-
if (isPinned(const_cast<chess::Board&>(board), pieceSq)) score -= 30;
121+
U64 pinnedPieces = myPieces; // Cache the bitboard
122+
while (pinnedPieces) {
123+
int pieceSq = __builtin_ctzll(pinnedPieces);
124+
pinnedPieces &= pinnedPieces - 1;
125+
if (isPinned(const_cast<chess::Board&>(board), chess::Square(pieceSq))) {
126+
score -= 30;
127+
}
124128
}
125129

126-
// **2. Skewer Check** (Updated)
127-
for (chess::Square attackerSq : scan_reversed(board.pieces(chess::PieceType::ROOK, board.sideToMove()).getBits() |
128-
board.pieces(chess::PieceType::QUEEN, board.sideToMove()).getBits())) {
129-
for (chess::Square targetSq : scan_reversed(board.them(board.sideToMove()).getBits())) {
130-
for (chess::Square behindTargetSq : scan_reversed(board.them(board.sideToMove()).getBits())) {
131-
if (isSkewer(1ULL<<attackerSq.index(), 1ULL<<targetSq.index(), 1ULL<<behindTargetSq.index())) {
132-
score += 40; // Skewer usually wins material
130+
// **2. Skewer Check** (Optimized)
131+
U64 skewerAttackers = board.pieces(chess::PieceType::ROOK, board.sideToMove()).getBits() |
132+
board.pieces(chess::PieceType::QUEEN, board.sideToMove()).getBits();
133+
while (skewerAttackers) {
134+
int attackerSq = __builtin_ctzll(skewerAttackers);
135+
skewerAttackers &= skewerAttackers - 1;
136+
137+
U64 targetPieces = enemyPieces; // Cache enemy bitboard
138+
while (targetPieces) {
139+
int targetSq = __builtin_ctzll(targetPieces);
140+
targetPieces &= targetPieces - 1;
141+
142+
U64 behindTarget = enemyPieces;
143+
while (behindTarget) {
144+
int behindTargetSq = __builtin_ctzll(behindTarget);
145+
behindTarget &= behindTarget - 1;
146+
147+
if (isSkewer(1ULL << attackerSq, 1ULL << targetSq, 1ULL << behindTargetSq)) {
148+
score += 40;
133149
}
134150
}
135151
}
136152
}
137153

138-
// **3. Discovered Attack Check** (Updated)
139-
for (chess::Square movingSq : scan_reversed(board.us(board.sideToMove()).getBits())) {
140-
for (chess::Square attackerSq : scan_reversed(board.pieces(chess::PieceType::underlying::ROOK, board.sideToMove()).getBits() |
141-
board.pieces(chess::PieceType::underlying::BISHOP, board.sideToMove()).getBits() |
142-
board.pieces(chess::PieceType::underlying::QUEEN, board.sideToMove()).getBits())) {
143-
for (chess::Square targetSq : scan_reversed(board.them(board.sideToMove()).getBits())) {
144-
if (isDiscoveredAttack(1ULL<<movingSq.index(), 1ULL<<attackerSq.index(), 1ULL<<targetSq.index())) {
145-
score += 30; // Discovered attacks are strong
146-
}
154+
// **3. Discovered Attack Check (Optimized)**
155+
U64 mySlidingPieces = board.pieces(chess::PieceType::ROOK, board.sideToMove()).getBits() |
156+
board.pieces(chess::PieceType::BISHOP, board.sideToMove()).getBits() |
157+
board.pieces(chess::PieceType::QUEEN, board.sideToMove()).getBits();
158+
while (mySlidingPieces) {
159+
int attackerSq = __builtin_ctzll(mySlidingPieces);
160+
mySlidingPieces &= mySlidingPieces - 1;
161+
162+
U64 targets = enemyPieces;
163+
while (targets) {
164+
int targetSq = __builtin_ctzll(targets);
165+
targets &= targets - 1;
166+
167+
if (isDiscoveredAttack(1ULL << attackerSq, 1ULL << attackerSq, 1ULL << targetSq)) {
168+
score += 30;
147169
}
148170
}
149171
}
150172

151-
// **4. X-Ray Attack**
152-
for (chess::Square pieceSq : scan_reversed(board.pieces(chess::PieceType::underlying::ROOK, board.sideToMove()).getBits() |
153-
board.pieces(chess::PieceType::underlying::QUEEN, board.sideToMove()).getBits())) {
154-
for (chess::Square enemyPieceSq : scan_reversed(board.them(board.sideToMove()).getBits())) {
155-
if (isXRayAttack(board.pieces(chess::PieceType::underlying::QUEEN, board.sideToMove()).getBits(),
156-
board.pieces(chess::PieceType::underlying::ROOK, board.sideToMove()).getBits(),
157-
1ULL<<enemyPieceSq.index())) {
173+
// **4. X-Ray Attack Check**
174+
U64 xRayPieces = board.pieces(chess::PieceType::ROOK, board.sideToMove()).getBits() |
175+
board.pieces(chess::PieceType::QUEEN, board.sideToMove()).getBits();
176+
while (xRayPieces) {
177+
int pieceSq = __builtin_ctzll(xRayPieces);
178+
xRayPieces &= xRayPieces - 1;
179+
180+
U64 enemyTargets = enemyPieces;
181+
while (enemyTargets) {
182+
int enemyPieceSq = __builtin_ctzll(enemyTargets);
183+
enemyTargets &= enemyTargets - 1;
184+
185+
if (isXRayAttack(1ULL << pieceSq, 1ULL << enemyPieceSq, 1ULL << board.kingSq(~board.sideToMove()).index())) {
158186
score += 10;
159187
}
160188
}
161189
}
190+
162191
tacticsCache[hash] = score;
163192
return score;
164193
}
165194

195+
166196
// **8. King Patterns (Mobility & Escape Routes)**
167197
inline U64 getKingMobility(U64 king, U64 friendlyPieces) {
168198
return (king << 8 | king >> 8 | king << 1 | king >> 1) & ~friendlyPieces;

0 commit comments

Comments
 (0)