Skip to content

Commit ef6bc41

Browse files
committed
better time optimization
1 parent 30d1dda commit ef6bc41

File tree

6 files changed

+172
-129
lines changed

6 files changed

+172
-129
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ all: $(EXEC)
1313

1414
# Linking the object files into the executable
1515
$(EXEC): $(OBJ)
16-
$(CXX) $(CXXFLAGS) -std=c++17 -o $(EXEC) $(OBJ)
16+
$(CXX) $(LDFLAGS) -o $(EXEC) $(OBJ)
1717

1818
# Rule to build object files from source files
1919
%.o: %.cpp
20-
$(CXX) $(CXXFLAGS) -std=c++17 -c $< -o $@
20+
$(CXX) $(CXXFLAGS) -DNDEBUG -std=c++17 -c $< -o $@
2121

2222
# Clean up the compiled files
2323
clean:

eval.cpp

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

3-
// Define enum class for evaluation keys
4-
enum class EvalKey {
5-
DOUBLED, BACKWARD, BLOCKED, ISLANDED, ISOLATED, DBLISOLATED, WEAK, PAWNRACE,
6-
SHIELD, STORM, OUTPOST, LEVER, PAWNRAM, OPENPAWN, HOLES,
7-
UNDEV_KNIGHT, UNDEV_BISHOP, UNDEV_ROOK, DEV_QUEEN, OPEN_FILES,
8-
SEMI_OPEN_FILES, FIANCHETTO, TRAPPED, KEY_CENTER, SPACE,
9-
BADBISHOP, WEAKCOVER, MISSINGPAWN, ATTACK_ENEMY, K_OPENING,
10-
K_MIDDLE, K_END, PINNED, SKEWERED, DISCOVERED, FORK,
11-
TEMPO_FREEDOM_WEIGHT, TEMPO_OPPONENT_MOBILITY_PENALTY,
12-
UNDERPROMOTE, PAWN, KNIGHT, BISHOP, ROOK, QUEEN
13-
};
14-
// Struct to hold evaluation weights
15-
struct EvalWeights {
16-
static const std::unordered_map<EvalKey, int> weights;
17-
18-
static int getWeight(EvalKey key) {
19-
auto it = weights.find(key);
20-
return (it != weights.end()) ? it->second : 0; // Default if key not found
21-
}
22-
};
233
// Initialize static weight map
244
const std::unordered_map<EvalKey, int> EvalWeights::weights = {
255
{EvalKey::DOUBLED, 10}, {EvalKey::BACKWARD, 8}, {EvalKey::BLOCKED, 5},
@@ -36,9 +16,10 @@ const std::unordered_map<EvalKey, int> EvalWeights::weights = {
3616
{EvalKey::SKEWERED, 12}, {EvalKey::DISCOVERED, 14}, {EvalKey::FORK, 16},
3717
{EvalKey::TEMPO_FREEDOM_WEIGHT, 8}, {EvalKey::TEMPO_OPPONENT_MOBILITY_PENALTY, 6},
3818
{EvalKey::UNDERPROMOTE, 5}, {EvalKey::PAWN, 100}, {EvalKey::KNIGHT, 300},
39-
{EvalKey::BISHOP, 300}, {EvalKey::ROOK, 500}, {EvalKey::QUEEN, 900}
19+
{EvalKey::BISHOP, 300}, {EvalKey::ROOK, 500}, {EvalKey::QUEEN, 900},
20+
{EvalKey::COUNTER, 10}
4021
};
41-
std::unordered_map<U64, int> transposition; // Faster lookup
22+
//std::unordered_map<U64, int> transposition; // Faster lookup
4223

4324
// Declare only missing functions
4425
int evaluatePawnStructure(const chess::Position&);
@@ -129,6 +110,7 @@ std::vector<Square> scan_reversed(chess::Bitboard bb)
129110
}
130111
return iter;
131112
}
113+
#ifdef DBG
132114
// **1. Evaluate Bad Bishops**
133115
int evaluateBadBishops(const chess::Position& board) {
134116
auto myBishops = board.pieces(chess::PieceType::underlying::BISHOP, board.sideToMove());
@@ -144,6 +126,7 @@ int evaluateBadBishops(const chess::Position& board) {
144126
}
145127
return score;
146128
}
129+
#endif
147130
int evaluateKingSafety(const chess::Position& board) {
148131
// 1) One-time fetches
149132
const int side = board.sideToMove();
@@ -192,7 +175,7 @@ int evaluateKingSafety(const chess::Position& board) {
192175
int p = phase(board); // 1=open, 2=mid, 3=end
193176
return score * phaseWeight[p];
194177
}
195-
178+
#ifdef DBG
196179

197180
// **4. Evaluate Rooks on Open/Semi-Open Files**
198181
int evaluateRooksOnFiles(const chess::Position& board) {
@@ -943,6 +926,7 @@ int underpromote(chess::Position &board) {
943926

944927
return (lastMove.promotionType().internal() != chess::PieceType::QUEEN) ? reward : 0;
945928
}
929+
#endif
946930

947931
// PAWN
948932
const int PAWN_PSQT[2][64] = {
@@ -1126,12 +1110,15 @@ int psqt_eval(const chess::Position& board) {
11261110
}
11271111
return score; // Negate for Black
11281112
}
1129-
1113+
unsigned long long evalhits=0;
11301114
int eval(chess::Position &board) {
1131-
U64 hash = board.hash();
1115+
/*U64 hash = board.hash();
11321116
// Faster lookup & insertion
11331117
auto [it, inserted] = transposition.emplace(hash, 0);
1134-
if (!inserted) return it->second; // Already exists, return stored evaluation
1118+
if (!inserted){
1119+
++evalhits;
1120+
return it->second; // Already exists, return stored evaluation
1121+
}*/
11351122

11361123
// Precompute piece counts (avoid multiple function calls)
11371124
int pieceCount[10] = {
@@ -1155,36 +1142,40 @@ int eval(chess::Position &board) {
11551142
(EvalWeights::getWeight(EvalKey::QUEEN) * (pieceCount[4] - pieceCount[9]));
11561143

11571144
// Evaluate positional aspects
1145+
eval += evaluateKingSafety(board);
1146+
#ifdef DBG
11581147
eval += evaluatePawnStructure(board);
11591148
eval += evaluatePieces(board);
1160-
eval += evaluateKingSafety(board);
11611149
eval += evaluateTactics(board);
11621150
eval += piece_activity(board);
11631151
eval += development(board);
11641152
eval += rook_placement(board);
11651153
eval += center_control(board);
11661154
eval += key_center_squares_control(board);
1167-
eval += psqt_eval(board);
11681155
eval += evaluatePieceActivity(board);
1156+
#endif
1157+
eval += psqt_eval(board);
11691158
board.makeNullMove();
11701159
// Evaluate positional aspects
1160+
eval -= evaluateKingSafety(board);
1161+
#ifdef DBG
11711162
eval -= evaluatePawnStructure(board);
11721163
eval -= evaluatePieces(board);
1173-
eval -= evaluateKingSafety(board);
11741164
eval -= evaluateTactics(board);
11751165
eval -= piece_activity(board);
11761166
eval -= development(board);
11771167
eval -= rook_placement(board);
11781168
eval -= center_control(board);
11791169
eval -= key_center_squares_control(board);
1180-
eval -= psqt_eval(board);
11811170
eval -= evaluatePieceActivity(board);
1171+
#endif
1172+
eval -= psqt_eval(board);
11821173
board.unmakeNullMove();
11831174

1184-
it->second = eval; // Store result
1175+
//it->second = eval; // Store result
11851176
return eval;
11861177
}
1187-
1178+
#ifdef DBG
11881179
// Use `const chess::Position&` to avoid copies
11891180
int evaluatePawnStructure(const chess::Position& board) {
11901181
chess::Position b=board;
@@ -1199,6 +1190,7 @@ int evaluatePieces(const chess::Position& board) {
11991190
return -(evaluateBadBishops(board) + evaluateTrappedPieces(board) + evaluateKnightForks(board)) +
12001191
(evaluateFianchetto(board) + evaluateRooksOnFiles(board));
12011192
}
1193+
#endif
12021194
int piece_value(chess::PieceType piece) {
12031195
static const int lookup[] = {
12041196
0, // NONE

eval.h

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@
7575
return 64;
7676
}
7777
#endif
78+
#if defined(__GNUC__) || defined(__clang__)
79+
#define RESTRICT __restrict__
80+
#elif defined(_MSC_VER)
81+
#define RESTRICT __restrict
82+
#else
83+
#define RESTRICT
84+
#endif
85+
7886
namespace chess{
7987
class Position : public Board {
8088
public:
@@ -148,5 +156,25 @@ inline U64 southWest(U64 b) { return (b & ~FILE_A) >> 9; }
148156
#define MAX_MATE 32000
149157
#define MATE(i) (MAX-i)
150158
#define MATE_DISTANCE(i) (i-MAX_MATE)
151-
int eval(chess::Position&);
152-
int piece_value(chess::PieceType piece);
159+
int eval(chess::Position& RESTRICT board);
160+
int piece_value(chess::PieceType piece);
161+
// Define enum class for evaluation keys
162+
enum class EvalKey {
163+
DOUBLED, BACKWARD, BLOCKED, ISLANDED, ISOLATED, DBLISOLATED, WEAK, PAWNRACE,
164+
SHIELD, STORM, OUTPOST, LEVER, PAWNRAM, OPENPAWN, HOLES,
165+
UNDEV_KNIGHT, UNDEV_BISHOP, UNDEV_ROOK, DEV_QUEEN, OPEN_FILES,
166+
SEMI_OPEN_FILES, FIANCHETTO, TRAPPED, KEY_CENTER, SPACE,
167+
BADBISHOP, WEAKCOVER, MISSINGPAWN, ATTACK_ENEMY, K_OPENING,
168+
K_MIDDLE, K_END, PINNED, SKEWERED, DISCOVERED, FORK,
169+
TEMPO_FREEDOM_WEIGHT, TEMPO_OPPONENT_MOBILITY_PENALTY,
170+
UNDERPROMOTE, PAWN, KNIGHT, BISHOP, ROOK, QUEEN, COUNTER
171+
};
172+
// Struct to hold evaluation weights
173+
struct EvalWeights {
174+
static const std::unordered_map<EvalKey, int> weights;
175+
176+
static int getWeight(EvalKey key) {
177+
auto it = weights.find(key);
178+
return (it != weights.end()) ? it->second : 0; // Default if key not found
179+
}
180+
};

main.cpp

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,50 @@
11
#include "chess.hpp"
22
#include "search.h"
33
#include <iostream>
4-
extern unsigned long long nodes;
5-
/*chess::Move find_best_move(chess::Board &board, int depth) {
6-
int bestScore = -MAX;
7-
chess::Move bestMove;
8-
chess::Movelist moves;
9-
// Use the movegen namespace explicitly to fill the list of legal moves
10-
chess::movegen::legalmoves(moves, board);
4+
extern unsigned long long nodes, evalhits, tthits;
5+
int searchRoot(chess::Position& board, int depth, int prevScore) {
6+
if (depth < 3) {
7+
return search(board, depth, -MAX, MAX, 0);
8+
}
119

12-
// Iterate through the Movelist using a range-based for loop
13-
for (const auto& move : moves) {
14-
board.makeMove(move); // Make the move
15-
int score = -search(board, depth - 1, -MAX, MAX, 0);
16-
board.unmakeMove(move); // Undo the move
10+
int window = 16;
11+
int alpha = prevScore - window;
12+
int beta = prevScore + window;
13+
int score;
1714

18-
if (score > bestScore) {
19-
bestScore = score;
20-
bestMove = move;
15+
while (true) {
16+
score = search(board, depth, alpha, beta, 0);
17+
if (score <= alpha) {
18+
alpha -= window;
19+
} else if (score >= beta) {
20+
beta += window;
21+
} else {
22+
break;
2123
}
24+
window *= 2;
2225
}
2326

24-
return bestMove;
25-
}*/
27+
return score;
28+
}
29+
int main() {
30+
chess::Position board("8/2P5/pk1B4/6b1/7p/8/PP3PB1/1K6 b - - 0 40");
31+
int prevScore = 0;
32+
33+
for (int i = 1; i <= 10; ++i) {
34+
clock_t t1 = clock();
35+
36+
int score = search(board, i, -MAX, MAX, 0);//searchRoot(board, i, prevScore);
37+
38+
clock_t t2 = clock();
39+
double seconds = double(t2 - t1) / CLOCKS_PER_SEC;
40+
printf("\n%i %i %llu %llu %llu %.2f NPS\n", i, score, nodes, evalhits, tthits, nodes/seconds);
41+
t1=clock();
42+
printPV(board);
43+
t2=clock();
44+
printf("\nPV time: %.2f seconds\n", double(t2 - t1) / CLOCKS_PER_SEC);
45+
prevScore = score;
46+
nodes = 0, evalhits=0, tthits=0;
47+
}
2648

27-
int main(){
28-
chess::Position board("8/2P5/pk1B4/6b1/7p/8/PP3PB1/1K6 b - - 0 40");
29-
for (int i=1;i<=MAX_DEPTH;++i){
30-
printf("%i ", i);
31-
auto s=search(board,i,-MAX,MAX,0);
32-
printf("%i %llu\n", s, nodes);
33-
printPV(board);
34-
nodes=0;
35-
}
36-
return 0;
49+
return 0;
3750
}

0 commit comments

Comments
 (0)