Skip to content

Commit 82dd915

Browse files
committed
UCI-compilant added for debugging reasons
1 parent 14e5504 commit 82dd915

File tree

7 files changed

+160
-83
lines changed

7 files changed

+160
-83
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
CXX = g++
33

44
# Source files and object files
5-
SRC = main.cpp eval.cpp search.cpp tt.cpp
5+
SRC = main.cpp eval.cpp search.cpp tt.cpp move_ordering.cpp
66
OBJ = $(SRC:.cpp=.o)
77

88
# Output file

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# cppchess_engine
22

3-
A minimal chess engine (not UCI, not XBoard, but only search and evaluation functions)
3+
A minimal UCI-compilant (no time control now) chess engine
44

55
**Source**: [Disservin/chess-library](https://github.com/Disservin/chess-library)

main.cpp

Lines changed: 94 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,111 @@
44
#include "search.hpp"
55
#include "tt.hpp"
66
#include <iostream>
7+
#include <sstream>
8+
#include <string>
79
#include <ctime>
10+
11+
using namespace std;
12+
813
int main()
914
{
1015
chess::Position board;
11-
int prevScore = 0;
16+
string line;
17+
18+
cout << "id name MyEngine" << endl;
19+
cout << "id author YourNameHere" << endl;
20+
cout << "uciok" << endl;
1221

13-
for (int depth = 1; depth <= 6; ++depth)
22+
while (getline(cin, line))
1423
{
15-
clock_t t1 = clock();
24+
istringstream iss(line);
25+
string token;
26+
iss >> token;
1627

17-
search::tt.newSearch(); // Reset timestamps per iteration
18-
int score = search::alphaBeta(board, -MATE(0), MATE(0), depth, 0);
28+
if (token == "uci")
29+
{
30+
cout << "id name MyEngine" << endl;
31+
cout << "id author YourNameHere" << endl;
32+
cout << "uciok" << endl;
33+
}
34+
else if (token == "isready")
35+
{
36+
cout << "readyok" << endl;
37+
}
38+
else if (token == "position")
39+
{
40+
string sub;
41+
iss >> sub;
1942

20-
clock_t t2 = clock();
21-
double seconds = double(t2 - t1) / CLOCKS_PER_SEC;
43+
if (sub == "startpos")
44+
{
45+
board.setFen(chess::constants::STARTPOS);
46+
if (iss >> sub && sub == "moves")
47+
{
48+
while (iss >> sub)
49+
{
50+
board.makeMove(chess::uci::uciToMove(board, sub));
51+
}
52+
}
53+
}
54+
else if (sub == "fen")
55+
{
56+
string fen, temp;
57+
fen = "";
58+
int fenParts = 6;
59+
while (fenParts-- && iss >> temp)
60+
{
61+
fen += temp + " ";
62+
}
63+
board.setFen(fen);
64+
if (iss >> sub && sub == "moves")
65+
{
66+
while (iss >> sub)
67+
{
68+
board.makeMove(chess::uci::uciToMove(board, sub));
69+
}
70+
}
71+
}
72+
}
73+
else if (token == "go")
74+
{
75+
int depth = 6;
76+
string sub;
77+
while (iss >> sub)
78+
{
79+
if (sub == "depth")
80+
iss >> depth;
81+
}
82+
if (depth < 1)
83+
depth = 1;
84+
chess::Move best,ponder;
85+
for (int i = 1; i <= depth; i++)
86+
{
87+
clock_t t1 = clock();
2288

23-
printf("\nDepth: %d | Score: %d | Nodes: %llu | TT Hits: %llu | TT Misses: %llu | NPS: %.2f\n",
24-
depth, score, search::nodes, tthits, ttmiss, search::nodes / seconds);
89+
search::tt.newSearch();
90+
int16_t score = search::alphaBeta(board, -MATE(0), MATE(0), i);
2591

26-
search::printPV(board);
92+
clock_t t2 = clock();
93+
double seconds = double(t2 - t1) / CLOCKS_PER_SEC;
94+
best = search::pv.argmove[0];
95+
ponder = search::pv.argmove[1];
96+
fprintf(stderr, "info depth %d score cp %d nodes %llu time %d nps %.0f\n",
97+
i, score, search::nodes, (t2-t1)*1000/CLOCKS_PER_SEC, search::nodes / seconds);
2798

28-
prevScore = score;
29-
search::nodes = 0;
30-
search::tt.clear_stats();
99+
}
100+
cout << "bestmove " << best;
101+
if (ponder != chess::Move())
102+
cout << " ponder " << ponder;
103+
cout << "\n";
104+
}
105+
else if (token == "d"){
106+
cout << board << endl;
107+
}
108+
else if (token == "quit")
109+
{
110+
break;
111+
}
31112
}
32113

33114
return 0;

move_ordering.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include "move_ordering.hpp"
2+
namespace move_ordering
3+
{
4+
void moveOrder(chess::Position &board, chess::Movelist &moves, int ply)
5+
{
6+
7+
const chess::Move prev = board.move_stack.empty() ? chess::Move() : board.move_stack.back();
8+
const int side = (int)board.sideToMove();
9+
10+
for (int i = 0; i < moves.size(); i++) {
11+
chess::Move& move = moves[i]; // Get a reference to allow score modification
12+
int score = 0;
13+
14+
if (board.isCapture(move)) {
15+
auto victim = board.at(move.to()).type();
16+
auto attacker = board.at(move.from()).type();
17+
score += SCORE_CAPTURE + mvvLva(victim, attacker);
18+
}
19+
20+
if (move == counterMove[prev.from().index()][prev.to().index()]) {
21+
score += SCORE_COUNTER;
22+
}
23+
24+
if (move == killerMoves[0][ply]) score += SCORE_KILLER;
25+
else if (move == killerMoves[1][ply]) score += SCORE_KILLER / 2;
26+
27+
score += history[side][move.from().index()][move.to().index()] * SCORE_HISTORY;
28+
29+
move.setScore(score); // Use the public setter
30+
}
31+
32+
// Sort moves in descending order of score
33+
std::sort(moves.begin(), moves.end(), [](const chess::Move& a, const chess::Move& b) {
34+
return a.score() > b.score(); // Use the public getter
35+
});
36+
}
37+
}

move_ordering.hpp

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,45 +22,7 @@ inline int mvvLva(chess::PieceType victim, chess::PieceType attacker) {
2222
inline chess::Move counterMove[64][64];
2323
inline int16_t history[2][64][64] = {};
2424
inline chess::Move killerMoves[2][128] = {};
25-
26-
inline void moveOrder(chess::Position& board, chess::Movelist& moves, int ply) {
27-
static thread_local std::vector<std::pair<chess::Move, int>> scoredMoves;
28-
scoredMoves.clear();
29-
scoredMoves.reserve(moves.size());
30-
const chess::Move prev = board.move_stack.empty() ? chess::Move() : board.move_stack.back();
31-
const int side = (int)board.sideToMove();
32-
33-
for (int i = 0; i < moves.size(); i++) {
34-
const chess::Move& move = moves[i];
35-
int score = 0;
36-
37-
if (board.isCapture(move)) {
38-
auto victim = board.at(move.to()).type();
39-
auto attacker = board.at(move.from()).type();
40-
score += SCORE_CAPTURE + mvvLva(victim, attacker);
41-
}
42-
43-
if (move == counterMove[prev.from().index()][prev.to().index()]) {
44-
score += SCORE_COUNTER;
45-
}
46-
47-
if (move == killerMoves[0][ply]) score += SCORE_KILLER;
48-
else if (move == killerMoves[1][ply]) score += SCORE_KILLER / 2;
49-
50-
score += history[side][move.from().index()][move.to().index()] * SCORE_HISTORY;
51-
52-
scoredMoves.push_back({move, score});
53-
}
54-
55-
std::sort(scoredMoves.begin(), scoredMoves.end(), [](const auto& a, const auto& b) {
56-
return a.second > b.second;
57-
});
58-
59-
moves.clear();
60-
for (const auto& [move, _] : scoredMoves) {
61-
moves.add(move);
62-
}
63-
}
25+
void moveOrder(chess::Position& board, chess::Movelist& moves, int ply);
6426

6527
inline void updateKillers(chess::Move move, int ply) {
6628
if (killerMoves[0][ply] != move) {

search.cpp

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,10 @@ namespace search
44
{
55
// Transposition table
66
TranspositionTable tt(20);
7-
// Principal variation
8-
chess::Move pv[256];
97

10-
void updatePV(int ply, chess::Move best_move) {
11-
chess::Move newPV[256];
12-
newPV[ply] = best_move;
13-
14-
int i = ply + 1;
15-
for (; i < 256 && pv[i] != chess::Move(); ++i)
16-
newPV[i] = pv[i];
17-
18-
newPV[i] = chess::Move(); // null-terminate
19-
20-
std::memcpy(pv + ply, newPV + ply, sizeof(chess::Move) * (i - ply + 1));
21-
}
22-
23-
int16_t alphaBeta(chess::Position &board, int16_t alpha, int16_t beta, int depth, int ply)
8+
int16_t alphaBeta(chess::Position &board, int16_t alpha, int16_t beta, int depth, int ply, PV *pv)
249
{
10+
PV _pv={0};
2511
nodes++;
2612
auto ttEntry = tt.probe(board.hash());
2713
if (ttEntry)
@@ -38,12 +24,6 @@ void updatePV(int ply, chess::Move best_move) {
3824
return ttEntry->score();
3925
}
4026
}
41-
if (ply == 0)
42-
{
43-
memset(pv, 0, sizeof(pv));
44-
nodes = 0;
45-
tt.clear_stats();
46-
}
4727
if (depth == 0)
4828
return quiescence(board, alpha, beta, ply);
4929

@@ -64,7 +44,7 @@ void updatePV(int ply, chess::Move best_move) {
6444
for (const auto &move : moves)
6545
{
6646
board.makeMove(move);
67-
int16_t score = -alphaBeta(board, -beta, -alpha, depth - 1, ply + 1);
47+
int16_t score = -alphaBeta(board, -beta, -alpha, depth - 1, ply + 1, &_pv);
6848
board.pop();
6949

7050
if (score >= beta)
@@ -76,7 +56,11 @@ void updatePV(int ply, chess::Move best_move) {
7656
{
7757
alpha = score;
7858
bestmove = move;
79-
updatePV(ply, bestmove); // Move + child PV
59+
pv->argmove[0] = move;
60+
61+
memcpy(pv->argmove + 1, _pv.argmove, _pv.cmove * sizeof(chess::Move));
62+
63+
pv->cmove = _pv.cmove + 1;
8064
foundPV = true;
8165
}
8266
}
@@ -111,12 +95,20 @@ void updatePV(int ply, chess::Move best_move) {
11195
}
11296
return alpha;
11397
}
114-
98+
PV pv;
99+
int16_t alphaBeta(chess::Position &board, int16_t alpha, int16_t beta, int depth)
100+
{
101+
memset(&pv, 0, sizeof(pv));
102+
pv.cmove = 0;
103+
nodes = 0;
104+
tt.clear_stats();
105+
return alphaBeta(board, alpha, beta, depth, 0, &pv);
106+
}
115107
void printPV(chess::Position &board)
116108
{
117109
std::cout << "Principal Variation: ";
118-
for (int i = 0; i < 256 && pv[i] != chess::Move(); i++)
119-
std::cout << pv[i] << " ";
110+
for (int i = 0; i < pv.cmove && pv.argmove[i] != chess::Move(); i++)
111+
std::cout << pv.argmove[i] << " ";
120112
std::cout << std::endl;
121113
}
122114
}

search.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@
55
#include "tt.hpp"
66
#include "move_ordering.hpp"
77
namespace search {
8-
8+
struct PV
9+
{
10+
int cmove; // Number of moves in the line.
11+
chess::Move argmove[256]; // The line.
12+
};
913
inline uint64_t nodes = 0;
1014

11-
int16_t alphaBeta(chess::Position& board, int16_t alpha, int16_t beta, int depth, int ply);
15+
int16_t alphaBeta(chess::Position& board, int16_t alpha, int16_t beta, int depth);
1216
int16_t quiescence(chess::Position& board, int16_t alpha, int16_t beta, int ply);
1317
void printPV(chess::Position& board);
1418
extern TranspositionTable tt;
19+
extern PV pv;
1520
} // namespace search

0 commit comments

Comments
 (0)