Skip to content

Commit 84643b7

Browse files
committed
a lil bit of tuning
1 parent 864a7a9 commit 84643b7

20 files changed

Lines changed: 1796 additions & 1540 deletions

‎CMakeLists.txt‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,15 @@ FetchContent_Declare(
1111
GIT_REPOSITORY https://github.com/winapiadmin/chesslib.git
1212
GIT_TAG main
1313
)
14-
FetchContent_MakeAvailable(chesslib)
15-
add_executable(engine "main.cpp" "timeman.cpp" "timeman.h" "eval.h" "eval.cpp" "tune.h" "ucioption.h" "tune.cpp" "ucioption.cpp" "tt.h" "tt.cpp" "uci.cpp" "uci.h" "search.h" "search.cpp" "score.h" "score.cpp" "movepick.h" "movepick.cpp")
16-
target_link_libraries(engine PRIVATE chesslib)
14+
FetchContent_Declare(
15+
tbprobe
16+
GIT_REPOSITORY https://github.com/winapiadmin/tb_probing_tool.git
17+
GIT_TAG main
18+
)
19+
set(BUILD_GAVIOTA OFF CACHE BOOL "Enable Gaviota TB probing" FORCE)
20+
FetchContent_MakeAvailable(chesslib tbprobe)
21+
add_executable(engine "main.cpp" "timeman.cpp" "timeman.h" "eval.h" "eval.cpp" "tune.h" "ucioption.h" "tune.cpp" "ucioption.cpp" "tt.h" "tt.cpp" "uci.cpp" "uci.h" "search.h" "search.cpp" "score.h" "score.cpp" "movepick.h" "movepick.cpp" "tb.h" "tb.cpp")
22+
target_link_libraries(engine PRIVATE chesslib syzygy_probe)
1723
target_include_directories(engine PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${chesslib_SOURCE_DIR})
1824
execute_process(
1925
COMMAND git rev-parse --short HEAD

‎eval.cpp‎

Lines changed: 377 additions & 285 deletions
Large diffs are not rendered by default.

‎eval.h‎

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,9 @@ constexpr bool is_valid(Value value) { return value != VALUE_NONE; }
2020

2121
constexpr bool is_win(Value value) { return value >= VALUE_TB_WIN_IN_MAX_PLY; }
2222

23-
constexpr bool is_loss(Value value) {
24-
return value <= VALUE_TB_LOSS_IN_MAX_PLY;
25-
}
23+
constexpr bool is_loss(Value value) { return value <= VALUE_TB_LOSS_IN_MAX_PLY; }
2624

27-
constexpr bool is_decisive(Value value) {
28-
return is_win(value) || is_loss(value);
29-
}
25+
constexpr bool is_decisive(Value value) { return is_win(value) || is_loss(value); }
3026
constexpr Value MATE(int i) { return VALUE_MATE - i; }
3127
constexpr Value MATE_DISTANCE(int i) { return VALUE_MATE - (i < 0 ? -i : i); }
3228
namespace eval {

‎main.cpp‎

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "search.h"
2+
#include "tb.h"
23
#include "tune.h"
34
#include "uci.h"
45
#include "ucioption.h"
@@ -8,19 +9,24 @@ using namespace engine;
89
#define STR(x) STR_HELPER(x)
910

1011
int main() {
11-
std::cout << std::unitbuf;
12-
std::cout << "cppchess_engine version " << BUILD_VERSION << '\n';
13-
options.add("Move Overhead", Option(10, 0, 1000));
14-
options.add("Hash", Option(16, 1, 1 << 25, [](const Option &o) {
15-
search::tt.resize(int(o));
16-
return std::nullopt;
17-
}));
12+
std::cout << std::unitbuf;
13+
std::cout << "cppchess_engine version " << BUILD_VERSION << '\n';
14+
options.add("Move Overhead", Option(10, 0, 1000));
15+
options.add("Hash", Option(16, 1, 1 << 25, [](const Option &o) {
16+
search::tt.resize(int(o));
17+
return std::nullopt;
18+
}));
1819

19-
options.add("Clear Hash", Option(+[](const Option &) {
20-
search::tt.clear();
20+
options.add("Clear Hash", Option(+[](const Option &) {
21+
search::tt.clear();
2122

22-
return std::nullopt;
23-
}));
24-
Tune::init(options);
25-
loop();
23+
return std::nullopt;
24+
}));
25+
// work in progress
26+
options.add("SyzygyPath", Option("", [](const Option &o) {
27+
tb::init(std::string(o));
28+
return std::nullopt;
29+
}));
30+
Tune::init(options);
31+
loop();
2632
}

‎movepick.cpp‎

Lines changed: 77 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,37 +6,83 @@ using namespace chess;
66
using engine::eval::piece_value;
77
namespace engine::movepick {
88

9-
void orderMoves(chess::Board &board, chess::Movelist &moves, chess::Move ttMove,
10-
int ply, const engine::search::Session &session) {
11-
std::vector<std::pair<chess::Move, Value>> scoredMoves;
12-
scoredMoves.reserve(moves.size());
13-
14-
for (const auto &move : moves) {
15-
Value score = 0;
16-
17-
if (move == ttMove)
18-
score = 10000;
19-
else if (board.isCapture(move))
20-
score = ((move.type_of() & EN_PASSANT) == 0
21-
? piece_value(board.at<PieceType>(move.to()))
22-
: piece_value(PAWN)) *
23-
10 -
24-
piece_value(board.at<PieceType>(move.from()));
25-
else if (move == session.killerMoves[ply][0])
26-
score = 8500;
27-
else if (move == session.killerMoves[ply][1])
28-
score = 8000;
29-
else
30-
score = session.historyHeuristic[move.from()][move.to()];
31-
32-
scoredMoves.emplace_back(move, score);
33-
}
9+
static Bitboard att(PieceType pt, Square sq, Bitboard occ) {
10+
switch (pt) {
11+
case BISHOP: return attacks::bishop(sq, occ);
12+
case ROOK: return attacks::rook(sq, occ);
13+
case QUEEN: return attacks::queen(sq, occ);
14+
default: return 0;
15+
}
16+
}
3417

35-
std::stable_sort(
36-
scoredMoves.begin(), scoredMoves.end(),
37-
[](const auto &a, const auto &b) { return a.second > b.second; });
18+
Value see(Board& board, Move move) {
19+
if (move.type_of() == EN_PASSANT)
20+
return piece_value(PAWN);
21+
PieceType captured = board.at<PieceType>(move.to());
22+
if (captured == NO_PIECE_TYPE)
23+
return 0;
24+
PieceType attacker = board.at<PieceType>(move.from());
25+
Bitboard occ = board.occ() ^ (1ULL << move.from());
26+
Bitboard attackers = board.attackers(WHITE, move.to(), occ) | board.attackers(BLACK, move.to(), occ);
27+
Value gain[32];
28+
int d = 0;
29+
gain[d] = piece_value(captured);
30+
Color stm = ~board.side_to_move();
31+
while (++d < 32) {
32+
gain[d] = piece_value(attacker) - gain[d - 1];
33+
if (gain[d] < 0)
34+
break;
35+
attackers &= occ;
36+
Bitboard stmAttackers = attackers & board.occ(stm);
37+
if (!stmAttackers)
38+
break;
39+
Square sq = (Square)pop_lsb(stmAttackers);
40+
attacker = board.at<PieceType>(sq);
41+
if (attacker == NO_PIECE_TYPE)
42+
break;
43+
if (attacker == BISHOP || attacker == ROOK || attacker == QUEEN)
44+
attackers |= att(attacker, move.to(), occ);
45+
occ ^= (1ULL << sq);
46+
stm = ~stm;
47+
}
48+
while (--d)
49+
gain[d - 1] = -gain[d];
50+
return gain[0];
51+
}
3852

39-
for (size_t i = 0; i < scoredMoves.size(); ++i)
40-
moves[i] = scoredMoves[i].first;
53+
void orderMoves(Board &board, Movelist &moves, Move ttMove, int ply, const engine::search::Session &session, Move prevMove) {
54+
Value scores[300];
55+
size_t n = moves.size();
56+
for (size_t i = 0; i < n; ++i) {
57+
Move move = moves[i];
58+
if (move == ttMove)
59+
scores[i] = 10000;
60+
else if (board.isCapture(move)) {
61+
Value s = see(board, move);
62+
Value capturedVal = move.type_of() == EN_PASSANT ? piece_value(PAWN) : piece_value(board.at<PieceType>(move.to()));
63+
Value attackerVal = piece_value(board.at<PieceType>(move.from()));
64+
scores[i] = (s >= -50 ? 9000 : 4000) + std::max(s, Value(-50)) + (capturedVal * 10 - attackerVal) / 100;
65+
} else if (move == session.killerMoves[ply][0])
66+
scores[i] = 8500;
67+
else if (move == session.killerMoves[ply][1])
68+
scores[i] = 8000;
69+
else if (prevMove.is_ok() && move == session.counterMoves[prevMove.from_to()])
70+
scores[i] = 7500;
71+
else if (board.givesCheck(move) != CheckType::NO_CHECK)
72+
scores[i] = 7000;
73+
else
74+
scores[i] = session.historyHeuristic[move.from()][move.to()];
75+
}
76+
size_t limit = std::min(n, size_t(12));
77+
for (size_t i = 0; i + 1 < limit; ++i) {
78+
size_t best = i;
79+
for (size_t j = i + 1; j < n; ++j)
80+
if (scores[j] > scores[best])
81+
best = j;
82+
if (best != i) {
83+
std::swap(moves[i], moves[best]);
84+
std::swap(scores[i], scores[best]);
85+
}
86+
}
4187
}
42-
} // namespace engine::movepick
88+
} // namespace engine::movepick

‎movepick.h‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#pragma once
2+
#include "eval.h"
23
#include <fwd_decl.h>
34
namespace engine::search {
45
struct Session;
56
} // namespace engine::search
67
namespace engine::movepick {
7-
void orderMoves(chess::Board &, chess::Movelist &, chess::Move, int,
8-
const engine::search::Session &);
8+
void orderMoves(chess::Board &, chess::Movelist &, chess::Move, int, const engine::search::Session &, chess::Move);
9+
Value see(chess::Board &, chess::Move);
910
} // namespace engine::movepick

‎score.cpp‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
#include <cmath>
44
namespace engine {
55
Score::Score(Value v) {
6-
assert(-VALUE_INFINITE < v && v < VALUE_INFINITE);
6+
assert(-VALUE_INFINITE < v && v < VALUE_INFINITE);
77

8-
if (!is_decisive(v)) {
9-
score = InternalUnits{v};
10-
} else if (std::abs(v) <= VALUE_TB) {
11-
auto distance = VALUE_TB - std::abs(v);
12-
score = (v > 0) ? Tablebase{distance, true} : Tablebase{-distance, false};
13-
} else {
14-
auto distance = VALUE_MATE - std::abs(v);
15-
score = (v > 0) ? Mate{distance} : Mate{-distance};
16-
}
8+
if (!is_decisive(v)) {
9+
score = InternalUnits{ v };
10+
} else if (std::abs(v) <= VALUE_TB) {
11+
auto distance = VALUE_TB - std::abs(v);
12+
score = (v > 0) ? Tablebase{ distance, true } : Tablebase{ -distance, false };
13+
} else {
14+
auto distance = VALUE_MATE - std::abs(v);
15+
score = (v > 0) ? Mate{ distance } : Mate{ -distance };
16+
}
1717
}
1818
} // namespace engine

‎score.h‎

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,35 +25,31 @@
2525
namespace engine {
2626

2727
class Score {
28-
public:
29-
struct Mate {
30-
int plies;
31-
};
28+
public:
29+
struct Mate {
30+
int plies;
31+
};
3232

33-
struct Tablebase {
34-
int plies;
35-
bool win;
36-
};
33+
struct Tablebase {
34+
int plies;
35+
bool win;
36+
};
3737

38-
struct InternalUnits {
39-
int value;
40-
};
38+
struct InternalUnits {
39+
int value;
40+
};
4141

42-
Score() = default;
43-
Score(Value v);
42+
Score() = default;
43+
Score(Value v);
4444

45-
template <typename T> bool is() const {
46-
return std::holds_alternative<T>(score);
47-
}
45+
template <typename T> bool is() const { return std::holds_alternative<T>(score); }
4846

49-
template <typename T> T get() const { return std::get<T>(score); }
47+
template <typename T> T get() const { return std::get<T>(score); }
5048

51-
template <typename F> decltype(auto) visit(F &&f) const {
52-
return std::visit(std::forward<F>(f), score);
53-
}
49+
template <typename F> decltype(auto) visit(F &&f) const { return std::visit(std::forward<F>(f), score); }
5450

55-
private:
56-
std::variant<Mate, Tablebase, InternalUnits> score;
51+
private:
52+
std::variant<Mate, Tablebase, InternalUnits> score;
5753
};
5854

5955
} // namespace engine

0 commit comments

Comments
 (0)