-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
110 lines (94 loc) · 3.83 KB
/
Copy pathmain.cpp
File metadata and controls
110 lines (94 loc) · 3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include "board.h"
#include "movegen.h"
#include "nnue.h"
#include "uci.h"
#include "search.h"
#include <cstdio>
#if defined(_WIN32)
#include <io.h>
#else
#include <unistd.h>
#endif
#include "datagen.h"
#include <iostream>
#include <vector>
#include <stdexcept>
#include <filesystem>
namespace {
bool is_interactive_terminal() {
#if defined(_WIN32)
return _isatty(_fileno(stdin)) != 0 && _isatty(_fileno(stdout)) != 0;
#else
return isatty(fileno(stdin)) != 0 && isatty(fileno(stdout)) != 0;
#endif
}
void print_startup_wordmark() {
if (!is_interactive_terminal())
return;
std::cout
<< " _____\n"
<< " / __ \\\n"
<< " | / \\/ ___ ___ ___\n"
<< " | | / _ \\ / __/ _ \\\n"
<< " | \\__/\\ (_) | (_| (_) |\n"
<< " \\____/\\___/ \\___\\___/\n"
<< "\n";
}
} // namespace
int main(int argc, char* argv[]) {
// Disable I/O buffering for UCI pipe compatibility on Windows.
// Without this, stdout is fully buffered when connected to a pipe,
// causing the parent process (e.g., lichess-bot) to never receive responses.
// NOTE: We intentionally keep sync_with_stdio(true) (the default) so that
// std::cout shares the same unbuffered FILE* stream set by setbuf.
std::setbuf(stdout, nullptr);
std::setbuf(stdin, nullptr);
// 1. Initialize engine systems
Board::init_zobrist();
init_all_attack_tables();
Search::init_search_tables();
// Default play always uses this executable's embedded network. External
// networks are loaded only by an explicit EvalFile request.
if (!g_nnue.load_network("<embedded>")) {
std::cerr << "Error: Embedded NNUE network does not match this build." << std::endl;
return 1;
}
// Keep UCI stdout pristine for GUIs and match runners, while showing the
// Coco wordmark when a person launches the engine directly in a terminal.
print_startup_wordmark();
// Parse arguments safely
std::vector<std::string> args(argv, argv + argc);
for (size_t i = 1; i < args.size(); ++i) {
if (args[i] == "--datagen" && i + 3 < args.size()) {
try {
const long long target_positions = std::stoll(args[i + 1]);
const int num_threads = std::stoi(args[i + 2]);
const std::string output_path = args[i + 3];
DatagenOptions options;
options.engine_path = std::filesystem::absolute(args[0]).string();
for (size_t j = i + 4; j < args.size(); ++j) {
if (args[j] == "--seed" && j + 1 < args.size())
options.seed = std::stoull(args[++j]);
else if (args[j] == "--book" && j + 1 < args.size())
options.opening_book_path = args[++j];
else if (args[j] == "--buffer" && j + 1 < args.size())
options.buffer_positions = std::stoull(args[++j]);
else if (args[j] == "--datagen-tt" && j + 1 < args.size())
options.tt_mb_per_worker = std::stoull(args[++j]);
else if (args[j] == "--manifest" && j + 1 < args.size())
options.manifest_path = args[++j];
else
throw std::invalid_argument("unknown or incomplete datagen option: " + args[j]);
}
std::cout << "[Coco Engine] Initializing Native C++ Data Generator Subsystem..." << std::endl;
return run_datagen(target_positions, num_threads, output_path, options) ? 0 : 1;
} catch (const std::exception& error) {
std::cerr << "Invalid datagen arguments: " << error.what() << '\n';
return 1;
}
}
}
// 2. Start the UCI protocol listener loop (master loop)
uci_loop();
return 0;
}