Skip to content

Commit

Permalink
add fast check for balance1 search in opengen
Browse files Browse the repository at this point in the history
  • Loading branch information
dhbloo committed Oct 7, 2024
1 parent fac00cf commit ca25cf5
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 29 deletions.
7 changes: 5 additions & 2 deletions Rapfi/command/argutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,11 @@ Opening::OpeningGenConfig Command::parseOpengenConfig(const cxxopts::ParseResult
cfg.localSizeMin = result["min-area-size"].as<int>();
cfg.localSizeMax = result["max-area-size"].as<int>();
cfg.balance1Nodes = result["balance1-node"].as<size_t>();
cfg.balance2Nodes = result["balance2-node"].as<size_t>();
cfg.balanceWindow = Value(result["balance-window"].as<int>());
cfg.balance1FastCheckNodes =
static_cast<uint64_t>(result["balance1-fast-check-ratio"].as<double>() * cfg.balance1Nodes);
cfg.balance1FastCheckWindow = Value(result["balance1-fast-check-window"].as<int>());
cfg.balance2Nodes = result["balance2-node"].as<size_t>();
cfg.balanceWindow = Value(result["balance-window"].as<int>());

if (cfg.minMoves <= 0 || cfg.maxMoves < cfg.minMoves)
throw std::invalid_argument("condition 0 < minMove <= maxMove does no satisfy");
Expand Down
13 changes: 10 additions & 3 deletions Rapfi/command/opengen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ void Command::opengen(int argc, char *argv[])
("n,number", "Number of openings to generate", cxxopts::value<size_t>()) //
("o,output",
"Save openings to a text file (default to stdout if not specified)",
cxxopts::value<std::string>()) //
cxxopts::value<std::string>()) //
("s,boardsize", "Board size in [5,22]", cxxopts::value<int>()->default_value("15")) //
("r,rule",
"One of [freestyle, standard, renju] rule",
Expand All @@ -72,6 +72,13 @@ void Command::opengen(int argc, char *argv[])
("balance1-node",
"Maximal nodes for balance1 search",
cxxopts::value<uint64_t>()->default_value(std::to_string(cfg.balance1Nodes))) //
("balance1-fast-check-ratio",
"Spend how much amount of nodes to fast check if this position is balanceable",
cxxopts::value<double>()->default_value(
std::to_string((double)cfg.balance1FastCheckNodes / (double)cfg.balance1Nodes))) //
("balance1-fast-check-window",
"Consider this position as unbalanceable if its initial value falls outside the window",
cxxopts::value<int>()->default_value(std::to_string(cfg.balance1FastCheckWindow))) //
("balance2-node",
"Maximal nodes for balance2 search",
cxxopts::value<uint64_t>()->default_value(std::to_string(cfg.balance2Nodes))) //
Expand Down Expand Up @@ -152,8 +159,8 @@ void Command::opengen(int argc, char *argv[])

// Print out generation progress over time
if (now() - lastTime >= reportInterval) {
MESSAGEL("Generated " << i << " of " << numOpenings << " openings, opening/s = "
<< i / ((now() - startTime) / 1000.0));
MESSAGEL("Generated " << i << " of " << numOpenings << " openings, opening/min = "
<< i / ((now() - startTime) / 60000.0));
lastTime = now();
}
}
Expand Down
61 changes: 40 additions & 21 deletions Rapfi/search/opening.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,18 +341,22 @@ bool OpeningGenerator::next()
if (config.balance1Nodes) {
if (Config::MessageMode != MsgMode::NONE)
MESSAGEL("Searching balanced1 for opening " << board.positionString());
if (putBalance1Move())
if (putBalance1Move()) {
board.move(rule, Search::Threads.main()->rootMoves[0].pv[0]);
return true;
}
}

if (config.balance2Nodes && board.ply() > 2) {
board.undo(rule); // undo the move put by balance1
if (config.balance2Nodes && board.ply() > 1) {
board.undo(rule); // undo one random move

if (Config::MessageMode != MsgMode::NONE)
MESSAGEL("Searching balanced2 for opening " << board.positionString());
if (putBalance2Move())
if (putBalance2Move()) {
board.move(rule, Search::Threads.main()->rootMoves[0].pv[0]);
board.move(rule, Search::Threads.main()->rootMoves[0].pv[1]);
return true;
}
}

return false;
Expand Down Expand Up @@ -394,48 +398,63 @@ void OpeningGenerator::putRandomMoves(int numMoves, CandArea area)
/// @return True if successfully found a balanced move.
bool OpeningGenerator::putBalance1Move()
{
using Search::Threads;

// Setup search options
Search::SearchOptions options;
options.rule.rule = rule;
options.disableOpeningQuery = true;
options.balanceMode = Search::SearchOptions::BALANCE_ONE;
options.maxNodes = config.balance1Nodes;

Search::Threads.clear(false);
assert(!Search::Threads.empty());
Threads.clear(false);
assert(!Threads.empty());

// Start BALANCE1 search
Search::Threads.startThinking(board, options);
Search::Threads.waitForIdle();
// First do fast check to see if this position is balanceable
options.maxNodes = config.balance1FastCheckNodes;
if (options.maxNodes > 0) {
Threads.startThinking(board, options);
Threads.waitForIdle();

// Consider this position as unbalanceable if its initial value is too far
if (std::abs(Threads.main()->rootMoves[0].value) > config.balance1FastCheckWindow)
return false;
}

// Start the actual BALANCE1 search
options.maxNodes = std::max(config.balance1Nodes, config.balance1FastCheckNodes)
- config.balance1FastCheckNodes;
if (options.maxNodes > 0) {
Threads.startThinking(board, options);
Threads.waitForIdle();
}

// Check if BALANCE1 has find a move that is balanced enough
assert(!Search::Threads.main()->rootMoves.empty());
board.move(rule, Search::Threads.main()->rootMoves[0].pv[0]);
return std::abs(Search::Threads.main()->rootMoves[0].value) <= config.balanceWindow;
assert(!Threads.main()->rootMoves.empty());
return std::abs(Threads.main()->rootMoves[0].value) <= config.balanceWindow;
}

/// Put two moves to make a balanced opening.
/// @return True if successfully found a balanced move pair.
bool OpeningGenerator::putBalance2Move()
{
using Search::Threads;

// Setup search options
Search::SearchOptions options;
options.rule.rule = rule;
options.disableOpeningQuery = true;
options.balanceMode = Search::SearchOptions::BALANCE_TWO;
options.maxNodes = config.balance2Nodes;

Search::Threads.clear(false);
assert(!Search::Threads.empty());
Threads.clear(false);
assert(!Threads.empty());

// Try BALANCE2 search
Search::Threads.startThinking(board, options);
Search::Threads.waitForIdle();
Threads.startThinking(board, options);
Threads.waitForIdle();

assert(!Search::Threads.main()->rootMoves.empty());
board.move(rule, Search::Threads.main()->rootMoves[0].pv[0]);
board.move(rule, Search::Threads.main()->rootMoves[0].pv[1]);
return std::abs(Search::Threads.main()->rootMoves[0].value) <= config.balanceWindow;
assert(!Threads.main()->rootMoves.empty());
return std::abs(Threads.main()->rootMoves[0].value) <= config.balanceWindow;
}

} // namespace Opening
12 changes: 10 additions & 2 deletions Rapfi/search/opening.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void filterSymmetryMoves(const Board &board, std::vector<Pos> &moveList);
struct OpeningGenConfig
{
// How many moves one opening can have (0 < minMoves < maxMoves)
int minMoves = 1, maxMoves = 10;
int minMoves = 2, maxMoves = 10;

// Randomly picked moves are chosen inside a local square with size
// of [localSizeMin, localSizeMax]
Expand All @@ -63,14 +63,22 @@ struct OpeningGenConfig
// Find a balanced opening using search time limit of balanceNodes.
// If it is 0, then the generated openings will not be balanced.
uint64_t balance1Nodes = 1000000;

// Use how many nodes to fast check if this position is balanceable.
uint64_t balance1FastCheckNodes = 100000;

// When BALANCE1 is not able to find a balanced move, use how many
// extra nodes to find a balanced move pair in BALANCE2.
uint64_t balance2Nodes = 2000000;
uint64_t balance2Nodes = 2500000;

// Eval in [-balanceWindow, balanceWindow] is considered as balanced
// When we can not achieve a eval inside balance window using BALANCE1,
// BALANCE2 is tried instead;
Value balanceWindow = Value(50);

// Consider this position as unbalanceable if its initial search value
// falls outside this window.
Value balance1FastCheckWindow = Value(120);
};

/// OpeningGenerator class generates various (balanced) random opening using
Expand Down
2 changes: 1 addition & 1 deletion Rapfi/search/searchcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ struct SearchOptions
INFO_REALTIME = 0b01,
INFO_DETAIL = 0b10,
INFO_REALTIME_AND_DETAIL = 0b11,
} infoMode;
} infoMode = INFO_NONE;

// Time control
Time turnTime = 0;
Expand Down

0 comments on commit ca25cf5

Please sign in to comment.