Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,5 @@ engine/*.bin
*bullet*
*.txt
pzchessbot-linux-avx2-x86_64
*.bin
*.bin
test/test
32 changes: 24 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,45 @@ EVALFILE ?= nnue.bin

CXX := g++
CXXFLAGS := -std=c++17 -DNNUE_PATH=\"$(EVALFILE)\" -mavx2 -mbmi2 -mbmi -mavx -m64 -mpopcnt -mlzcnt
RELEASEFLAGS = -O3 -static
RELEASEFLAGS = -O3
DEBUGFLAGS = -g -fsanitize=address,undefined

SRCS := $(wildcard engine/*.cpp engine/nnue/*.cpp)
HDRS := $(wildcard engine/*.hpp engine/nnue/*.hpp)
OBJS := $(SRCS:.cpp=.o)
ROBJS := $(SRCS:.cpp=.o)
DOBJS := $(SRCS:.cpp=.d.o)

.PHONY: release debug clean
.PHONY: release debug test clean

release: CXXFLAGS += $(RELEASEFLAGS)
release: $(EXE)
release: CXXFLAGS += $(RELEASEFLAGS) -static
release: $(ROBJS)
make OBJS="$(ROBJS)" CXXFLAGS="$(CXXFLAGS) $(RELEASEFLAGS)" $(EXE)

debug: CXXFLAGS += $(DEBUGFLAGS)
debug: $(EXE)
debug: $(DOBJS)
make OBJS="$(DOBJS)" CXXFLAGS="$(CXXFLAGS) $(DEBUGFLAGS)" $(EXE)

$(EXE): $(OBJS)
$(CXX) $(CXXFLAGS) -o $@ $^
@echo "Build complete. Run with './$(EXE)'"

%.o: %.cpp $(HDRS)
%.o: %.cpp $(HDRS) Makefile
%.d.o: %.cpp $(HDRS) Makefile
$(CXX) $(CXXFLAGS) -c $< -o $@

debug-test: CXXFLAGS += $(DEBUGFLAGS)
debug-test: $(DOBJS)
$(AR) rcs test/objs.a $(DOBJS)
make -C test CXXFLAGS="$(CXXFLAGS)" debug

test: CXXFLAGS += $(RELEASEFLAGS)
test: $(ROBJS)
$(AR) rcs test/objs.a $(ROBJS)
make -C test CXXFLAGS="$(CXXFLAGS)"

clean:
@echo "Cleaning up..."
rm -f $(EXE)
rm -f $(OBJS)
rm -f $(ROBJS) $(DOBJS)
rm -f test/objs.a
make -C test clean
16 changes: 8 additions & 8 deletions engine/bitboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ void Board::load_fen(std::string fen) {
}

void Board::reset_board() {
memset(piece_boards, 0, sizeof(piece_boards));
piece_boards[0] = Rank2Bits | Rank7Bits; // Pawns
piece_boards[1] = square_bits(SQ_B1) | square_bits(SQ_G1) | square_bits(SQ_B8) | square_bits(SQ_G8); // Knights
piece_boards[2] = square_bits(SQ_C1) | square_bits(SQ_F1) | square_bits(SQ_C8) | square_bits(SQ_F8); // Bishops
Expand Down Expand Up @@ -240,22 +239,23 @@ std::string Board::get_fen() const {
}
res += side ? " b " : " w ";
if (castling == NO_CASTLE) {
res += "- ";
res += '-';
} else {
if (castling & WHITE_OO)
res += "K";
res += 'K';
if (castling & WHITE_OOO)
res += "Q";
res += 'Q';
if (castling & BLACK_OO)
res += "k";
res += 'k';
if (castling & BLACK_OOO)
res += "q";
res += 'q';
}

// En passant square
if (ep_square == SQ_NONE) {
if (ep_square >= SQ_NONE) {
res += " - ";
} else {
res += ' ';
res += 'a' + (ep_square & 0b111);
res += '1' + (ep_square >> 3);
res += ' ';
Expand Down Expand Up @@ -344,7 +344,7 @@ void Board::print_board() const {
std::cout << "q";
}

if (ep_square == SQ_NONE)
if (ep_square >= SQ_NONE)
std::cout << " - ";
else
std::cout << ' ' << (char)('a' + (ep_square & 0b111)) << (char)('1' + (ep_square >> 3)) << ' ';
Expand Down
21 changes: 3 additions & 18 deletions engine/bitboard.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,30 +72,15 @@ struct Board {
pzstd::largevector<uint64_t> hash_hist;

// Mailbox representation of the board for faster queries of certain data
Piece mailbox[8 * 8] = {WHITE_ROOK, WHITE_KNIGHT, WHITE_BISHOP, WHITE_QUEEN, WHITE_KING, WHITE_BISHOP, WHITE_KNIGHT, WHITE_ROOK,
WHITE_PAWN, WHITE_PAWN, WHITE_PAWN, WHITE_PAWN, WHITE_PAWN, WHITE_PAWN, WHITE_PAWN, WHITE_PAWN,
NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE,
NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE,
NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE,
NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE, NO_PIECE,
BLACK_PAWN, BLACK_PAWN, BLACK_PAWN, BLACK_PAWN, BLACK_PAWN, BLACK_PAWN, BLACK_PAWN, BLACK_PAWN,
BLACK_ROOK, BLACK_KNIGHT, BLACK_BISHOP, BLACK_QUEEN, BLACK_KING, BLACK_BISHOP, BLACK_KNIGHT, BLACK_ROOK};
Piece mailbox[8 * 8];

// Moves with extra information (taken piece etc..)
// better documentation will be included later
std::stack<HistoryEntry> move_hist;
std::stack<uint8_t> halfmove_hist;

Board(int ttsize=DEFAULT_TT_SIZE) : ttable(ttsize) {
// Load starting position
piece_boards[0] = Rank2Bits | Rank7Bits;
piece_boards[1] = square_bits(SQ_B1) | square_bits(SQ_G1) | square_bits(SQ_B8) | square_bits(SQ_G8);
piece_boards[2] = square_bits(SQ_C1) | square_bits(SQ_F1) | square_bits(SQ_C8) | square_bits(SQ_F8);
piece_boards[3] = square_bits(SQ_A1) | square_bits(SQ_H1) | square_bits(SQ_A8) | square_bits(SQ_H8);
piece_boards[4] = square_bits(SQ_D1) | square_bits(SQ_D8);
piece_boards[5] = square_bits(SQ_E1) | square_bits(SQ_E8);
piece_boards[6] = Rank1Bits | Rank2Bits;
piece_boards[7] = Rank7Bits | Rank8Bits;
reset_board();
recompute_hash();
}

Expand All @@ -118,9 +103,9 @@ struct Board {

void legal_moves(pzstd::vector<Move> &) const;
std::pair<int, int> control(int) const;
Value see(Square);
Value see_capture(Move);
Bitboard __lva(Square, int side, PieceType &p, Bitboard occ) const;
bool is_pseudolegal(Move) const;

void recompute_hash();

Expand Down
2 changes: 1 addition & 1 deletion engine/eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ float multi(int x) {
}
#endif

void init_network() {
__attribute__((constructor)) void init_network() {
#ifndef HCE
nnue_network.load();
for (int i = 0; i < HL_SIZE; i++) {
Expand Down
2 changes: 0 additions & 2 deletions engine/eval.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
#include "includes.hpp"
#include "boardstate.hpp"

void init_network();

Value simple_eval(Board &board);

Value eval(Board &board);
Expand Down
27 changes: 23 additions & 4 deletions engine/includes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ constexpr Value MAX_HISTORY = 16384;

#define CLOCKS_PER_MS (CLOCKS_PER_SEC / 1000)

// clang-format off

enum PieceType : uint8_t { PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING, NO_PIECETYPE };

enum Piece : uint8_t {
Expand All @@ -78,11 +80,9 @@ constexpr Value PieceValue[] = {PawnValue, KnightValue, BishopValue, RookValue,

enum CastlingRights : uint8_t { NO_CASTLE, WHITE_OO, WHITE_OOO = WHITE_OO << 1, BLACK_OO = WHITE_OO << 2, BLACK_OOO = WHITE_OO << 3 };

// clang-format off
constexpr PieceType letter_piece[] = {BISHOP, NO_PIECETYPE, NO_PIECETYPE, NO_PIECETYPE, NO_PIECETYPE, NO_PIECETYPE, NO_PIECETYPE, NO_PIECETYPE, NO_PIECETYPE, KING, NO_PIECETYPE, NO_PIECETYPE, KNIGHT, NO_PIECETYPE, PAWN, QUEEN, ROOK};
constexpr char piecetype_letter[] = {'p', 'n', 'b', 'r', 'q', 'k', '?'};
constexpr char piece_letter[] = {'P','N','B','R','Q','K','?','?','p','n','b','r','q','k','?'};
// clang-format on

enum File : uint16_t {
FILE_A,
Expand All @@ -95,6 +95,10 @@ enum File : uint16_t {
FILE_H,
};

inline constexpr File operator++(File &file, int) {
return file = File(file + 1);
}

enum Rank : uint16_t {
RANK_1,
RANK_2,
Expand All @@ -106,7 +110,10 @@ enum Rank : uint16_t {
RANK_8,
};

// clang-format off
inline constexpr Rank operator++(Rank &rank, int) {
return rank = Rank(rank + 1);
}

enum Square : uint16_t {
SQ_A1, SQ_B1, SQ_C1, SQ_D1, SQ_E1, SQ_F1, SQ_G1, SQ_H1,
SQ_A2, SQ_B2, SQ_C2, SQ_D2, SQ_E2, SQ_F2, SQ_G2, SQ_H2,
Expand All @@ -118,7 +125,19 @@ enum Square : uint16_t {
SQ_A8, SQ_B8, SQ_C8, SQ_D8, SQ_E8, SQ_F8, SQ_G8, SQ_H8,
SQ_NONE
};
// clang-format on

inline constexpr Square make_square(File file, Rank rank) {
return Square(file + rank * 8);
}

inline constexpr Square operator++(Square &square, int) {
return square = Square(square + 1);
}

inline std::string to_string(Square square) {
if (square >= SQ_NONE) return "None";
return std::string(1, 'a' + (square % 8)) + std::to_string(1 + (square / 8));
}

enum MoveType {
NORMAL,
Expand Down
22 changes: 12 additions & 10 deletions engine/main.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "includes.hpp"

#include <random>
#include <sstream>
#include <thread>
#include <random>

#include "bitboard.hpp"
#include "eval.hpp"
Expand All @@ -12,9 +12,11 @@

BoardState bs;

// Options
int TT_SIZE = DEFAULT_TT_SIZE;
bool quiet = false;

int main(int argc, char *argv[]) {
__attribute__((weak)) int main(int argc, char *argv[]) {
if (argc == 2 && std::string(argv[1]) == "bench") {
const std::pair<std::string, int> bench_positions[] = {
{"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", 12},
Expand All @@ -24,7 +26,6 @@ int main(int argc, char *argv[]) {
{"k7/8/8/8/8/8/8/K6R w - - 0 1", 20},
};
Board board = Board(TT_SIZE);
init_network();
uint64_t tot_nodes = 0;
uint64_t start = clock();
for (const auto &[fen, depth] : bench_positions) {
Expand Down Expand Up @@ -52,7 +53,6 @@ int main(int argc, char *argv[]) {
ss >> token; // ignore book for now
}
Board board = Board(TT_SIZE);
init_network();
std::mt19937 rng(s);
while (n--) {
board.reset_startpos();
Expand All @@ -78,14 +78,14 @@ int main(int argc, char *argv[]) {
std::cout << "PZChessBot " << VERSION << " developed by kevlu8 and wdotmathree" << std::endl;
std::string command;
Board board = Board(TT_SIZE);
init_network();
std::thread searchthread;
while (getline(std::cin, command)) {
if (command == "uci") {
std::cout << "id name PZChessBot " << VERSION << std::endl;
std::cout << "id author kevlu8 and wdotmathree" << std::endl;
std::cout << "option name Hash type spin default 16 min 1 max 1024" << std::endl;
std::cout << "option name Threads type spin default 1 min 1 max 1" << std::endl; // Not implemented yet
std::cout << "option name Quiet type check default false" << std::endl;
std::cout << "uciok" << std::endl;
} else if (command == "isready") {
std::cout << "readyok" << std::endl;
Expand All @@ -107,6 +107,8 @@ int main(int argc, char *argv[]) {
continue;
}
TT_SIZE = optionint * 1024 * 1024 / sizeof(TTable::TTBucket);
} else if (optionname == "Quiet") {
quiet = optionvalue == "true";
}
} else if (command == "ucinewgame") {
board = Board(TT_SIZE);
Expand Down Expand Up @@ -185,15 +187,15 @@ int main(int argc, char *argv[]) {
int inc = board.side ? binc : winc;
std::pair<Move, Value> res;
if (inf)
res = search(board);
res = search(board, quiet = quiet);
else if (depth != -1)
res = search_depth(board, depth);
res = search_depth(board, depth, quiet);
else if (nodes != -1)
res = search_nodes(board, nodes);
res = search_nodes(board, nodes, quiet);
else if (movetime != -1)
res = search(board, movetime);
res = search(board, movetime, quiet);
else
res = search(board, timemgmt(timeleft, inc, online));
res = search(board, timemgmt(timeleft, inc, online), quiet);
std::cout << "bestmove " << res.first.to_string() << std::endl;
}
}
Expand Down
Loading