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
27 changes: 19 additions & 8 deletions ben-bot/include/ben-bot/Engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <functional>
#include <libbenbot/search/Thread.hpp>
#include <libchess/game/Position.hpp>
#include <libchess/moves/Move.hpp>
#include <libchess/uci/CommandParsing.hpp>
#include <libchess/uci/EngineBase.hpp>
#include <libchess/uci/Options.hpp>
Expand All @@ -35,6 +36,7 @@
namespace ben_bot {

using chess::game::Position;
using chess::moves::Move;
using std::string_view;

namespace uci = chess::uci;
Expand Down Expand Up @@ -83,6 +85,8 @@ class [[nodiscard]] Engine final : public uci::EngineBase {

void set_pretty_printing(bool shouldPrettyPrint);

[[nodiscard]] auto pretty_print_move(Move move) const -> std::string;

static void print_compiler_info();

static void start_file_logger(string_view path);
Expand All @@ -99,7 +103,7 @@ class [[nodiscard]] Engine final : public uci::EngineBase {
uci::IntOption ttSize {
"Hash",
1, 2048, 16,
"Sets the maximum transposition table size (in MB)",
"Sets the maximum transposition table size (in MB).",
[this](const int sizeMB) {
wait();
searcher.context.transTable.resize(
Expand All @@ -110,7 +114,7 @@ class [[nodiscard]] Engine final : public uci::EngineBase {
uci::Action clearTT {
"Clear Hash",
[this] { searcher.context.clear_transposition_table(); },
"Press to clear the transposition table"
"Press to clear the transposition table."
};

// The engine doesn't start pondering on its own without explicitly being told to
Expand All @@ -120,12 +124,12 @@ class [[nodiscard]] Engine final : public uci::EngineBase {
uci::BoolOption ponder {
"Ponder",
true,
"Controls whether pondering is allowed"
"Controls whether pondering is allowed."
};

uci::IntOption threads {
"Threads", 1, 1, 1,
"Number of searcher threads (currently a dummy)"
"Number of searcher threads (currently a dummy)."
};

uci::IntOption moveOverhead {
Expand All @@ -135,19 +139,26 @@ class [[nodiscard]] Engine final : public uci::EngineBase {

uci::StringOption logFile {
"Debug Log File", "<empty>",
"If not empty, engine I/O will be mirrored to this file",
"If not empty, engine I/O will be mirrored to this file.",
start_file_logger
};

uci::BoolOption prettyPrintMode {
"Pretty Print",
PRETTY_PRINT_DEFAULT,
"When on, search output is pretty-printed instead of printed in UCI format",
"When on, search output is pretty-printed instead of printed in UCI format.",
[this](const bool usePretty) { set_pretty_printing(usePretty); }
};

std::array<uci::Option*, 7uz> options {
&ttSize, &clearTT, &ponder, &threads, &moveOverhead, &logFile, &prettyPrintMode
uci::ComboOption moveFormat {
"Move Format",
{ "UCI", "Algebraic", "ICCF" },
"Algebraic",
"Notation format used to display moves in pretty printing mode."
};

std::array<uci::Option*, 8uz> options {
&ttSize, &clearTT, &ponder, &threads, &moveOverhead, &logFile, &prettyPrintMode, &moveFormat
};

/* ----- Custom commands ----- */
Expand Down
6 changes: 4 additions & 2 deletions ben-bot/src/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ void Engine::new_game(const bool firstCall)
// initializing them in the constructor to avoid referencing the
// `this` pointer in the constructor
if (prettyPrinting.load()) {
searcher.context.callbacks = search::Callbacks::make_pretty_printer();
searcher.context.callbacks = search::Callbacks::make_pretty_printer(
[this](const Move move) { return pretty_print_move(move); });
} else {
searcher.context.callbacks = search::Callbacks::make_uci_printer(
[this] noexcept { // cppcheck-suppress syntaxError
Expand All @@ -59,7 +60,8 @@ void Engine::set_pretty_printing(const bool shouldPrettyPrint)
wait();

if (shouldPrettyPrint) {
searcher.context.callbacks = search::Callbacks::make_pretty_printer();
searcher.context.callbacks = search::Callbacks::make_pretty_printer(
[this](const Move move) { return pretty_print_move(move); });
} else {
searcher.context.callbacks = search::Callbacks::make_uci_printer(
[this] noexcept { return debugMode.load(memory_order_relaxed); });
Expand Down
18 changes: 12 additions & 6 deletions ben-bot/src/Perft.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,31 @@

#include <ben-bot/Engine.hpp>
#include <format>
#include <functional>
#include <libchess/moves/Move.hpp>
#include <libchess/moves/Perft.hpp>
#include <libchess/notation/UCI.hpp>
#include <libchess/uci/Printing.hpp>
#include <libchess/util/Strings.hpp>
#include <print>
#include <string>

namespace ben_bot {

namespace util = chess::util;
namespace notation = chess::notation;
namespace util = chess::util;

using uci::printing::info_string;

namespace {
using chess::moves::PerftResult;

void print_root_nodes(const PerftResult& result)
void print_root_nodes(
const PerftResult& result,
const std::function<std::string(Move)>& printMove)
{
for (const auto& [move, numChildren] : result.rootNodes) {
info_string(std::format(
"Move {}: {} child nodes",
notation::to_uci(move), numChildren));
printMove(move), numChildren));
}
}

Expand Down Expand Up @@ -66,7 +69,10 @@ void Engine::run_perft(const string_view arguments) const
depth, searcher.context.options.position);

std::println("");
print_root_nodes(result);

print_root_nodes(
result,
[this](const Move move) { return pretty_print_move(move); });

std::println("");
print_results(result);
Expand Down
25 changes: 23 additions & 2 deletions ben-bot/src/Printing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
#include <libbenbot/eval/Evaluation.hpp>
#include <libbenbot/eval/Score.hpp>
#include <libbenbot/search/Result.hpp>
#include <libchess/notation/Algebraic.hpp>
#include <libchess/notation/FEN.hpp>
#include <libchess/notation/ICCF.hpp>
#include <libchess/notation/UCI.hpp>
#include <libchess/uci/Printing.hpp>
#include <libchess/util/Strings.hpp>
Expand All @@ -29,6 +31,7 @@
#include <print>
#include <string>
#include <string_view>
#include <utility>
#include <variant>

namespace ben_bot {
Expand Down Expand Up @@ -151,15 +154,15 @@ void Engine::print_current_position(const string_view arguments) const

searcher.context.transTable
.find(pos)
.transform([](const TTData& data) {
.transform([this](const TTData& data) {
print_labeled_info(
"TT hit: ",
std::format(
"depth {} eval {} type {} probed {} bestmove {}",
data.searchedDepth, data.eval,
magic_enum::enum_name(data.evalType),
eval::Score::from_tt(data.eval, 0uz),
chess::notation::to_uci(data.bestMove.value_or(Move { }))));
pretty_print_move(data.bestMove.value_or(Move { }))));

return std::monostate { };
});
Expand All @@ -182,4 +185,22 @@ void Engine::print_compiler_info()
resources::get_build_time()));
}

auto Engine::pretty_print_move(const Move move) const -> std::string
{
const auto format = moveFormat.get_value();

if (format == "UCI")
return chess::notation::to_uci(move);

if (format == "Algebraic")
return chess::notation::to_alg(
searcher.context.options.position, move);

if (format == "ICCF")
return chess::notation::to_iccf(move);

std::unreachable();
return { };
}

} // namespace ben_bot
11 changes: 10 additions & 1 deletion libbenbot/include/libbenbot/search/Callbacks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
#pragma once

#include <functional>
#include <string>

namespace chess::moves {
struct Move;
}

namespace ben_bot::search {

Expand Down Expand Up @@ -86,9 +91,13 @@ struct Callbacks final {
/** Creates a set of callbacks that print search information in a human-readable
table-aligned format.

@param printMove Function object that will be used to format Move objects to display
the PV.

@note The output produced by these callbacks does not conform to the UCI protocol!
*/
[[nodiscard]] static auto make_pretty_printer()
[[nodiscard]] static auto make_pretty_printer(
std::function<std::string(chess::moves::Move)>&& printMove)
-> Callbacks;
};

Expand Down
25 changes: 17 additions & 8 deletions libbenbot/src/search/Callbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include <libbenbot/search/Callbacks.hpp>
#include <libbenbot/search/Result.hpp>
#include <libchess/moves/Move.hpp>
#include <libchess/notation/UCI.hpp>
#include <libchess/uci/Printing.hpp>
#include <libchess/util/Chrono.hpp>
#include <libchess/util/Variant.hpp>
Expand Down Expand Up @@ -242,8 +241,11 @@ namespace {
std::cout << termcolor::reset;
}

using MovePrinter = std::function<std::string(Move)>;

[[nodiscard]] auto format_pv(
const std::span<const Move> pv) -> string
const std::span<const Move> pv,
const MovePrinter& printMove) -> string
{
if (pv.empty()) {
// this is possible if we're checkmated
Expand All @@ -253,7 +255,7 @@ namespace {
string result;

for (const auto move : pv) {
result.append(chess::notation::to_uci(move));
result.append(printMove(move));
result.append(1uz, ' ');
}

Expand Down Expand Up @@ -282,7 +284,8 @@ namespace {
<< termcolor::reset;
}

void pretty_print(const Result& res)
void pretty_print(
const Result& res, const MovePrinter& printMove)
{
// depth
print_column_text<Alignment::Center>(
Expand Down Expand Up @@ -310,19 +313,25 @@ namespace {
print_score(libchess.score);

// PV
std::cout << format_pv(res.pv) << '\n';
std::cout << format_pv(res.pv, printMove)
<< '\n';
}
} // namespace

auto Callbacks::make_pretty_printer()
auto Callbacks::make_pretty_printer(
MovePrinter&& printMove)
-> Callbacks
{
auto printIteration = [formatMove = std::move(printMove)](const Result& res) {
pretty_print(res, formatMove);
};

return {
.onSearchStart = []([[maybe_unused]] const Options& options) {
print_table_header();
},
.onSearchComplete = pretty_print,
.onIteration = pretty_print
.onSearchComplete = printIteration,
.onIteration = printIteration
};
}

Expand Down
Loading