Skip to content

Commit d25f275

Browse files
authored
A working version (but painfully slow)
1 parent d5afdb3 commit d25f275

File tree

11 files changed

+93
-88
lines changed

11 files changed

+93
-88
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Compiler and Flags
22
CXX = g++
3-
CXXFLAGS = -march=native -mtune=native -msse4.2 -std=c++17 $(FLAGS)
3+
CXXFLAGS = -march=native -mtune=native -msse4.2 -std=c++17 $(FLAGS) -DNDEBUG
44

55
# Source files and object files
66
SRC = main.cpp eval.cpp search.cpp pieces.cpp pawns.cpp patterns.cpp

eval.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#include "eval.h"
22

3-
3+
std::map<unsigned long long, int> transposition;
44
int eval(chess::Board board){
5+
if (transposition.count(board.hash())) return transposition[board.hash()];
6+
U64 hash=board.hash();
57
//Game over
68
if (board.inCheck()&&board.isGameOver().first!=chess::GameResultReason::NONE)return MAX;
79
else if (board.isGameOver().first!=chess::GameResultReason::NONE)return 0;
@@ -44,7 +46,7 @@ int eval(chess::Board board){
4446
eval += evaluateKingMobility(board);
4547
eval += evaluateSpaceControl(board);
4648
eval -= evaluateTactics(board);
47-
board.makeNullMove();
49+
board.pop();
4850
eval -= -isolated(board);
4951
eval -= -dblisolated(board);
5052
eval -= -weaks(board);
@@ -71,6 +73,6 @@ int eval(chess::Board board){
7173
eval += -evaluateKingMobility(board);
7274
eval += -evaluateSpaceControl(board);
7375
eval -= -evaluateTactics(board);
74-
board.unmakeNullMove();
76+
transposition[hash]=eval;
7577
return eval;
7678
}

eval.h

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
#ifndef EVAL
2-
#define EVAL
3-
#include "chess.hpp"
4-
#include "patterns.h"
5-
#include "pieces.h"
6-
#include <vector>
7-
#define MAX 32767 // for black
8-
#define MAX_MATE 32000
9-
#define Pawn 100
10-
#define Knight 300
11-
#define Bishop 300
12-
#define Rook 500
13-
#define Queen 900
14-
#define MATE(i) MAX-i
15-
#define MATE_DISTANCE(i) i-MAX_MATE
16-
int eval(chess::Board);
17-
#endif //EVAL
1+
#pragma once
2+
#include "chess.hpp"
3+
#include "patterns.h"
4+
#include "pieces.h"
5+
#include <map>
6+
#include <vector>
7+
#define MAX 32767 // for black
8+
#define MAX_MATE 32000
9+
#define Pawn 100
10+
#define Knight 300
11+
#define Bishop 300
12+
#define Rook 500
13+
#define Queen 900
14+
#define MATE(i) MAX-i
15+
#define MATE_DISTANCE(i) i-MAX_MATE
16+
int eval(chess::Board);

patterns.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ inline bool isDiscoveredAttack(U64 movingPiece, U64 attacker, U64 target) {
2121
inline bool isXRayAttack(U64 attacker, U64 blocker, U64 target) {
2222
return (attacker & blocker) && (attacker & target);
2323
}
24-
inline bool isTrappedPiece(const chess::Board board, chess::Square pieceSq) {
24+
inline bool isTrappedPiece(const chess::Board& board, chess::Square pieceSq) {
2525
chess::Piece piece = board.at(pieceSq);
2626
if (piece == chess::Piece::NONE) return false; // No piece → not trapped
2727

@@ -85,7 +85,7 @@ inline bool isTrappedPiece(const chess::Board board, chess::Square pieceSq) {
8585
}
8686

8787

88-
inline bool isPinned(chess::Board board, chess::Square pieceSq) {
88+
inline bool isPinned(chess::Board& board, chess::Square pieceSq) {
8989
chess::Color side = board.at(pieceSq).color();
9090
chess::Square kingSq = board.kingSq(side);
9191

@@ -96,15 +96,15 @@ inline bool isPinned(chess::Board board, chess::Square pieceSq) {
9696
return isPinned;
9797
}
9898

99-
int evaluateTactics(const chess::Board board) {
99+
int evaluateTactics(const chess::Board& board) {
100100
int score = 0;
101101

102102
chess::Square myKing = board.kingSq(board.sideToMove());
103103
chess::Square enemyKing = board.kingSq(~board.sideToMove());
104104

105105
// **1. Pin Check**
106106
for (chess::Square pieceSq : scan_reversed(board.us(board.sideToMove()).getBits())) {
107-
if (isPinned(board, pieceSq)) score -= 30;
107+
if (isPinned(const_cast<chess::Board&>(board), pieceSq)) score -= 30;
108108
}
109109

110110
// **2. Skewer Check** (Updated)

patterns.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
bool isLosingQueenPromotion(int, U64, U64, U64);
66
inline bool isLosingQueenPromotion(U64 $1, U64 $2, U64 $3, U64 $4){ return isLosingQueenPromotion(__builtin_ctzll($1), $2, $3, $4);}
7-
int evaluateTactics(const chess::Board board);
7+
int evaluateTactics(const chess::Board &board);

pawns.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ int backward(U64 whitePawns, U64 blackPawns) {
6262
inline U64 getBlockedPawns(U64 pawns, U64 enemyPieces, bool isWhite) {
6363
return isWhite ? north(pawns) & enemyPieces : south(pawns) & enemyPieces;
6464
}
65-
int blockage(chess::Board board){
65+
int blockage(chess::Board& board){
6666
return POPCOUNT64(getBlockedPawns(board.pieces(chess::PieceType::underlying::PAWN,board.sideToMove()).getBits(),board.them(board.sideToMove()).getBits(),(int)board.sideToMove()))*5;
6767
}
6868

@@ -73,7 +73,7 @@ inline U64 getHangingPawns(U64 pawns, U64 friendlyPieces) {
7373
return pawns & ~defended;
7474
}
7575

76-
int pawnIslands(chess::Board board){
76+
int pawnIslands(chess::Board& board){
7777

7878
int islands = 0;
7979
U64 remaining = board.pieces(chess::PieceType::underlying::PAWN, board.sideToMove()).getBits();
@@ -97,22 +97,22 @@ inline U64 getDoublyIsolatedPawns(U64 pawns) {
9797
U64 isolated = getIsolatedPawns(pawns);
9898
return isolated & (isolated - 1); // More than one isolated pawn in a file
9999
}
100-
int isolated(chess::Board board){
100+
int isolated(chess::Board& board){
101101
return POPCOUNT64(getIsolatedPawns(board.pieces(chess::PieceType::underlying::PAWN,board.sideToMove()).getBits()))*5;
102102
}
103-
int dblisolated(chess::Board board){
103+
int dblisolated(chess::Board& board){
104104
return POPCOUNT64(getDoublyIsolatedPawns(board.pieces(chess::PieceType::underlying::PAWN,board.sideToMove()).getBits()))*10;
105105
}
106106
// **2. Holes** (Uncontested squares that cannot be controlled by pawns)
107107
inline U64 getHoles(U64 whitePawns, U64 blackPawns) {
108108
U64 pawnControl = north(whitePawns) | south(blackPawns);
109109
return ~pawnControl; // Holes are squares not controlled by any pawn
110110
}
111-
int holes(chess::Board board){
111+
int holes(chess::Board& board){
112112
return POPCOUNT64(getHoles(board.pieces(chess::PieceType::underlying::PAWN,chess::Color::underlying::WHITE).getBits(),board.pieces(chess::PieceType::underlying::PAWN,chess::Color::underlying::BLACK).getBits()))*5;
113113
}
114114

115-
int pawnRace(chess::Board board) {
115+
int pawnRace(chess::Board& board) {
116116
U64 myPawns = board.pieces(chess::PieceType::PAWN, board.sideToMove()).getBits();
117117
int minDistance = 8; // Maximum distance to promotion
118118
while (myPawns) {
@@ -131,7 +131,7 @@ inline U64 getWeakPawns(U64 pawns, U64 enemyPawns) {
131131
U64 backward = (north(pawns) & enemyPawns) | (south(pawns) & enemyPawns);
132132
return isolated | backward; // Any pawn that is weak
133133
}
134-
int weaks(chess::Board board){
134+
int weaks(chess::Board& board){
135135
return POPCOUNT64(getWeakPawns(board.pieces(chess::PieceType::underlying::PAWN,board.sideToMove()).getBits(),board.pieces(chess::PieceType::underlying::PAWN,~board.sideToMove()).getBits()))*6;
136136
}
137137
inline U64 getKingMobility(U64 king, U64 enemyPieces) {
@@ -170,7 +170,7 @@ inline bool shouldUnderpromote(U64 pawn, U64 enemyKing, bool isWhite, U64 enemyP
170170

171171
return false; // Default: Queen promotion is optimal
172172
}
173-
int underpromote(chess::Board board) {
173+
int underpromote(chess::Board& board) {
174174
if (board.move_stack.empty()) return 0; // No moves to undo → no underpromotion
175175
chess::Move move = board.pop();
176176

@@ -217,14 +217,14 @@ int underpromote(chess::Board board) {
217217
inline U64 getColorWeakness(U64 pawns) {
218218
return ~((pawns & DARK_SQUARES) | (pawns & LIGHT_SQUARES)); // Weak squares
219219
}
220-
int weakness(chess::Board board){
220+
int weakness(chess::Board& board){
221221
return POPCOUNT64(getColorWeakness(board.pieces(chess::PieceType::underlying::PAWN,board.sideToMove()).getBits()))*10;
222222
}
223223
// **5. Pawn Shield (King Protection by Pawns)**
224224
inline U64 getPawnShield(U64 king, U64 pawns, bool isWhite) {
225225
return isWhite ? (north(king) & pawns) : (south(king) & pawns);
226226
}
227-
int pawnShield(chess::Board board){
227+
int pawnShield(chess::Board& board){
228228
return POPCOUNT64(getPawnShield(1ULL<<board.kingSq(board.sideToMove()).index(),board.pieces(chess::PieceType::underlying::PAWN,board.sideToMove()).getBits(),(int)board.sideToMove()))*5;
229229
}
230230

@@ -258,37 +258,37 @@ inline U64 getOpenPawns(U64 pawns, U64 enemyPawns) {
258258
return pawns & ~(north(pawns) & enemyPawns); // No enemy directly in front
259259
}
260260

261-
int pawnStorm(chess::Board board) {
261+
int pawnStorm(chess::Board& board) {
262262
U64 myPawns = board.pieces(chess::PieceType::PAWN, board.sideToMove()).getBits();
263263
U64 storm = board.sideToMove() ? north(myPawns) | north(north(myPawns))
264264
: south(myPawns) | south(south(myPawns));
265265
return POPCOUNT64(storm) * 5; // Bonus for aggressive pawn pushes
266266
}
267267

268-
int pawnLevers(chess::Board board) {
268+
int pawnLevers(chess::Board& board) {
269269
U64 myPawns = board.pieces(chess::PieceType::PAWN, board.sideToMove()).getBits();
270270
U64 enemyPawns = board.pieces(chess::PieceType::PAWN, ~board.sideToMove()).getBits();
271271
return POPCOUNT64(getPawnLevers(myPawns, enemyPawns)) * 5; // Bonus for break opportunities
272272
}
273273

274-
int outpost(chess::Board board) {
274+
int outpost(chess::Board& board) {
275275
U64 myKnights = board.pieces(chess::PieceType::KNIGHT, board.sideToMove()).getBits();
276276
U64 myPawns = board.pieces(chess::PieceType::PAWN, board.sideToMove()).getBits();
277277
return POPCOUNT64(getOutposts(myKnights, myPawns, board.sideToMove())) * 10; // Reward strong knights
278278
}
279-
int evaluatePawnRams(chess::Board board) {
279+
int evaluatePawnRams(chess::Board& board) {
280280
return POPCOUNT64(getPawnRams(
281281
board.pieces(chess::PieceType::PAWN, board.sideToMove()).getBits(),
282282
board.pieces(chess::PieceType::PAWN, ~board.sideToMove()).getBits())) * 5;
283283
}
284284

285-
int evaluateUnfreePawns(chess::Board board) {
285+
int evaluateUnfreePawns(chess::Board& board) {
286286
return POPCOUNT64(getUnfreePawns(
287287
board.pieces(chess::PieceType::PAWN, board.sideToMove()).getBits(),
288288
board.pieces(chess::PieceType::PAWN, ~board.sideToMove()).getBits())) * 7;
289289
}
290290

291-
int evaluateOpenPawns(chess::Board board) {
291+
int evaluateOpenPawns(chess::Board& board) {
292292
return POPCOUNT64(getOpenPawns(
293293
board.pieces(chess::PieceType::PAWN, board.sideToMove()).getBits(),
294294
board.pieces(chess::PieceType::PAWN, ~board.sideToMove()).getBits())) * 3;

pawns.h

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@
44
// **Evaluation Function Declarations**
55
int doubled(U64, U64);
66
int backward(U64, U64);
7-
int weaks(chess::Board);
8-
int blockage(chess::Board);
9-
int pawnIslands(chess::Board);
10-
int isolated(chess::Board);
11-
int dblisolated(chess::Board);
12-
int holes(chess::Board);
13-
int pawnRace(chess::Board);
14-
int underpromote(chess::Board);
15-
int weakness(chess::Board);
16-
int pawnShield(chess::Board);
17-
int pawnStorm(chess::Board);
18-
int pawnLevers(chess::Board);
19-
int outpost(chess::Board);
20-
int evaluatePawnRams(chess::Board);
21-
int evaluateUnfreePawns(chess::Board);
22-
int evaluateOpenPawns(chess::Board);
7+
int weaks(chess::Board&);
8+
int blockage(chess::Board&);
9+
int pawnIslands(chess::Board&);
10+
int isolated(chess::Board&);
11+
int dblisolated(chess::Board&);
12+
int holes(chess::Board&);
13+
int pawnRace(chess::Board&);
14+
int underpromote(chess::Board&);
15+
int weakness(chess::Board&);
16+
int pawnShield(chess::Board&);
17+
int pawnStorm(chess::Board&);
18+
int pawnLevers(chess::Board&);
19+
int outpost(chess::Board&);
20+
int evaluatePawnRams(chess::Board&);
21+
int evaluateUnfreePawns(chess::Board&);
22+
int evaluateOpenPawns(chess::Board&);

pieces.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ int getGamePhase(int whiteKnights, int whiteBishops, int whiteRooks, int whiteQu
3131
return 3; // Endgame
3232
}
3333
}
34-
int phase(const chess::Board board) {
34+
int phase(const chess::Board& board) {
3535
int whiteKnights = POPCOUNT64(board.pieces(chess::PieceType::underlying::KNIGHT, chess::Color::underlying::WHITE).getBits());
3636
int whiteBishops = POPCOUNT64(board.pieces(chess::PieceType::underlying::BISHOP, chess::Color::underlying::WHITE).getBits());
3737
int whiteRooks = POPCOUNT64(board.pieces(chess::PieceType::underlying::ROOK, chess::Color::underlying::WHITE).getBits());
@@ -211,7 +211,7 @@ std::vector<Square> scan_reversed(Bitboard bb)
211211
}
212212

213213
// **1. Evaluate Bad Bishops**
214-
int evaluateBadBishops(const chess::Board board) {
214+
int evaluateBadBishops(const chess::Board& board) {
215215
U64 myBishops = board.pieces(chess::PieceType::underlying::BISHOP, board.sideToMove()).getBits();
216216
U64 myPawns = board.pieces(chess::PieceType::underlying::PAWN, board.sideToMove()).getBits();
217217

@@ -227,7 +227,7 @@ int evaluateBadBishops(const chess::Board board) {
227227
}
228228

229229
// **2. Evaluate King Safety**
230-
int evaluateKingSafety(const chess::Board board) {
230+
int evaluateKingSafety(const chess::Board& board) {
231231
U64 king = 1ULL << board.kingSq(board.sideToMove()).index();
232232
U64 ownPawns = board.pieces(chess::PieceType::underlying::PAWN, board.sideToMove()).getBits();
233233
U64 enemyPieces = board.them(board.sideToMove()).getBits();
@@ -236,14 +236,14 @@ int evaluateKingSafety(const chess::Board board) {
236236
}
237237

238238
// **3. Evaluate King Pawn Tropism**
239-
int evaluateKingPawnTropism(const chess::Board board) {
239+
int evaluateKingPawnTropism(const chess::Board& board) {
240240
U64 king = 1ULL << board.kingSq(board.sideToMove()).index();
241241
U64 enemyPawns = board.pieces(chess::PieceType::underlying::PAWN, ~board.sideToMove()).getBits();
242242
return kingPawnTropism(king, enemyPawns) * -3; // Penalize proximity to enemy pawns
243243
}
244244

245245
// **4. Evaluate Rooks on Open/Semi-Open Files**
246-
int evaluateRooksOnFiles(const chess::Board board) {
246+
int evaluateRooksOnFiles(const chess::Board& board) {
247247
U64 myRooks = board.pieces(chess::PieceType::underlying::ROOK, board.sideToMove()).getBits();
248248
U64 myPawns = board.pieces(chess::PieceType::underlying::PAWN, board.sideToMove()).getBits();
249249

@@ -260,7 +260,7 @@ int evaluateRooksOnFiles(const chess::Board board) {
260260
}
261261

262262
// **5. Evaluate Fianchetto Bishops**
263-
int evaluateFianchetto(const chess::Board board) {
263+
int evaluateFianchetto(const chess::Board& board) {
264264
U64 myBishops = board.pieces(chess::PieceType::underlying::BISHOP, board.sideToMove()).getBits();
265265
U64 myPawns = board.pieces(chess::PieceType::underlying::PAWN, board.sideToMove()).getBits();
266266

@@ -276,15 +276,15 @@ int evaluateFianchetto(const chess::Board board) {
276276
}
277277

278278
// **6. Evaluate Trapped Pieces**
279-
int evaluateTrappedPieces(const chess::Board board) {
279+
int evaluateTrappedPieces(const chess::Board& board) {
280280
U64 myPieces = board.us(board.sideToMove()).getBits();
281281
U64 myPawns = board.pieces(chess::PieceType::underlying::PAWN, board.sideToMove()).getBits();
282282
U64 enemyAttacks = board.them(~board.sideToMove()).getBits();
283283

284284
return POPCOUNT64(getTrappedPieces(myPieces, myPawns, enemyAttacks)) * 10;
285285
}
286286

287-
int evaluateKnightForks(const chess::Board board) {
287+
int evaluateKnightForks(const chess::Board& board) {
288288
U64 myKnights = board.pieces(chess::PieceType::KNIGHT, board.sideToMove()).getBits();
289289
chess::Bitboard enemyPieces = board.them(board.sideToMove());
290290

@@ -305,21 +305,21 @@ int evaluateKnightForks(const chess::Board board) {
305305

306306

307307
// **8. Evaluate King Mobility**
308-
int evaluateKingMobility(const chess::Board board) {
308+
int evaluateKingMobility(const chess::Board& board) {
309309
U64 king = 1ULL << board.kingSq(board.sideToMove()).index();
310310
U64 myPieces = board.us(board.sideToMove()).getBits();
311311

312312
return POPCOUNT64(getKingMobility(king, myPieces)) * 3;
313313
}
314314

315315
// **9. Evaluate Space Control**
316-
int evaluateSpaceControl(const chess::Board board) {
316+
int evaluateSpaceControl(const chess::Board& board) {
317317
U64 myPawns = board.pieces(chess::PieceType::underlying::PAWN, board.sideToMove()).getBits();
318318
U64 enemyPawns = board.pieces(chess::PieceType::underlying::PAWN, ~board.sideToMove()).getBits();
319319

320320
return evaluateSpace(myPawns, enemyPawns, board.sideToMove());
321321
}
322-
int evaluateTempo(chess::Board board) {
322+
int evaluateTempo(chess::Board& board) {
323323
chess::Movelist myMoves, opponentMoves;
324324

325325
// Generate all legal moves for both sides

pieces.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@
33
#include "pawns.h"
44

55
// **1. Game Phase Evaluation**
6-
int phase(const chess::Board board);
6+
int phase(const chess::Board&);
77
// **2. Piece Activity Evaluations**
8-
int evaluateBadBishops(const chess::Board board);
9-
int evaluateFianchetto(const chess::Board board);
10-
int evaluateTrappedPieces(const chess::Board board);
11-
int evaluateKnightForks(const chess::Board board);
12-
int evaluateRooksOnFiles(const chess::Board board);
8+
int evaluateBadBishops(const chess::Board&);
9+
int evaluateFianchetto(const chess::Board&);
10+
int evaluateTrappedPieces(const chess::Board&);
11+
int evaluateKnightForks(const chess::Board&);
12+
int evaluateRooksOnFiles(const chess::Board&);
1313

1414
// **3. King Safety & Mobility Evaluations**
15-
int evaluateKingSafety(const chess::Board board);
16-
int evaluateKingPawnTropism(const chess::Board board);
17-
int evaluateKingMobility(const chess::Board board);
15+
int evaluateKingSafety(const chess::Board&);
16+
int evaluateKingPawnTropism(const chess::Board&);
17+
int evaluateKingMobility(const chess::Board&);
1818

1919
// **4. Positional & Space Evaluations**
20-
int evaluateSpaceControl(const chess::Board board);
21-
int evaluateTempo(const chess::Board board);
20+
int evaluateSpaceControl(const chess::Board&);
21+
int evaluateTempo(const chess::Board&);

0 commit comments

Comments
 (0)