1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-06-28 00:19:50 +00:00

Wording of help output and comments.

Improved the output text that is diplayed when executing the 'help' command.
Also, some comments were fixed along the way.

closes https://github.com/official-stockfish/Stockfish/pull/4048
closes https://github.com/official-stockfish/Stockfish/pull/4044

No functional change
This commit is contained in:
Boštjan Mejak 2022-05-31 20:25:57 +02:00 committed by Joost VandeVondele
parent 90cf8e7d2b
commit 809849fa27
3 changed files with 67 additions and 66 deletions

View file

@ -35,6 +35,7 @@ Ben Chaney (Chaneybenjamini)
Ben Koshy (BKSpurgeon) Ben Koshy (BKSpurgeon)
Bill Henry (VoyagerOne) Bill Henry (VoyagerOne)
Bojun Guo (noobpwnftw, Nooby) Bojun Guo (noobpwnftw, Nooby)
Boštjan Mejak (PedanticHacker)
braich braich
Brian Sheppard (SapphireBrand, briansheppard-toast) Brian Sheppard (SapphireBrand, briansheppard-toast)
Bruno de Melo Costa (BM123499) Bruno de Melo Costa (BM123499)

View file

@ -40,14 +40,14 @@ extern vector<string> setup_bench(const Position&, istream&);
namespace { namespace {
// FEN string of the initial position, normal chess // FEN string for the initial position in standard chess
const char* StartFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; const char* StartFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
// position() is called when engine receives the "position" UCI command. // position() is called when the engine receives the "position" UCI command.
// The function sets up the position described in the given FEN string ("fen") // It sets up the position that is described in the given FEN string ("fen") or
// or the starting position ("startpos") and then makes the moves given in the // the initial position ("startpos") and then makes the moves given in the following
// following move list ("moves"). // move list ("moves").
void position(Position& pos, istringstream& is, StateListPtr& states) { void position(Position& pos, istringstream& is, StateListPtr& states) {
@ -59,7 +59,7 @@ namespace {
if (token == "startpos") if (token == "startpos")
{ {
fen = StartFEN; fen = StartFEN;
is >> token; // Consume "moves" token if any is >> token; // Consume the "moves" token, if any
} }
else if (token == "fen") else if (token == "fen")
while (is >> token && token != "moves") while (is >> token && token != "moves")
@ -67,10 +67,10 @@ namespace {
else else
return; return;
states = StateListPtr(new std::deque<StateInfo>(1)); // Drop old and create a new one states = StateListPtr(new std::deque<StateInfo>(1)); // Drop the old state and create a new one
pos.set(fen, Options["UCI_Chess960"], &states->back(), Threads.main()); pos.set(fen, Options["UCI_Chess960"], &states->back(), Threads.main());
// Parse move list (if any) // Parse the move list, if any
while (is >> token && (m = UCI::to_move(pos, token)) != MOVE_NONE) while (is >> token && (m = UCI::to_move(pos, token)) != MOVE_NONE)
{ {
states->emplace_back(); states->emplace_back();
@ -78,8 +78,8 @@ namespace {
} }
} }
// trace_eval() prints the evaluation for the current position, consistent with the UCI // trace_eval() prints the evaluation of the current position, consistent with
// options set so far. // the UCI options set so far.
void trace_eval(Position& pos) { void trace_eval(Position& pos) {
@ -93,20 +93,20 @@ namespace {
} }
// setoption() is called when engine receives the "setoption" UCI command. The // setoption() is called when the engine receives the "setoption" UCI command.
// function updates the UCI option ("name") to the given value ("value"). // The function updates the UCI option ("name") to the given value ("value").
void setoption(istringstream& is) { void setoption(istringstream& is) {
string token, name, value; string token, name, value;
is >> token; // Consume "name" token is >> token; // Consume the "name" token
// Read option name (can contain spaces) // Read the option name (can contain spaces)
while (is >> token && token != "value") while (is >> token && token != "value")
name += (name.empty() ? "" : " ") + token; name += (name.empty() ? "" : " ") + token;
// Read option value (can contain spaces) // Read the option value (can contain spaces)
while (is >> token) while (is >> token)
value += (value.empty() ? "" : " ") + token; value += (value.empty() ? "" : " ") + token;
@ -117,9 +117,9 @@ namespace {
} }
// go() is called when engine receives the "go" UCI command. The function sets // go() is called when the engine receives the "go" UCI command. The function
// the thinking time and other parameters from the input string, then starts // sets the thinking time and other parameters from the input string, then starts
// the search. // with a search.
void go(Position& pos, istringstream& is, StateListPtr& states) { void go(Position& pos, istringstream& is, StateListPtr& states) {
@ -127,7 +127,7 @@ namespace {
string token; string token;
bool ponderMode = false; bool ponderMode = false;
limits.startTime = now(); // As early as possible! limits.startTime = now(); // The search starts as early as possible
while (is >> token) while (is >> token)
if (token == "searchmoves") // Needs to be the last command on the line if (token == "searchmoves") // Needs to be the last command on the line
@ -151,9 +151,9 @@ namespace {
} }
// bench() is called when engine receives the "bench" command. Firstly // bench() is called when the engine receives the "bench" command.
// a list of UCI commands is setup according to bench parameters, then // Firstly, a list of UCI commands is set up according to the bench
// it is run one by one printing a summary at the end. // parameters, then it is run one by one, printing a summary at the end.
void bench(Position& pos, istream& args, StateListPtr& states) { void bench(Position& pos, istream& args, StateListPtr& states) {
@ -184,12 +184,12 @@ namespace {
} }
else if (token == "setoption") setoption(is); else if (token == "setoption") setoption(is);
else if (token == "position") position(pos, is, states); else if (token == "position") position(pos, is, states);
else if (token == "ucinewgame") { Search::clear(); elapsed = now(); } // Search::clear() may take some while else if (token == "ucinewgame") { Search::clear(); elapsed = now(); } // Search::clear() may take a while
} }
elapsed = now() - elapsed + 1; // Ensure positivity to avoid a 'divide by zero' elapsed = now() - elapsed + 1; // Ensure positivity to avoid a 'divide by zero'
dbg_print(); // Just before exiting dbg_print();
cerr << "\n===========================" cerr << "\n==========================="
<< "\nTotal time (ms) : " << elapsed << "\nTotal time (ms) : " << elapsed
@ -197,36 +197,36 @@ namespace {
<< "\nNodes/second : " << 1000 * nodes / elapsed << endl; << "\nNodes/second : " << 1000 * nodes / elapsed << endl;
} }
// The win rate model returns the probability (per mille) of winning given an eval // The win rate model returns the probability of winning (in per mille units) given an
// and a game-ply. The model fits rather accurately the LTC fishtest statistics. // eval and a game ply. It fits the LTC fishtest statistics rather accurately.
int win_rate_model(Value v, int ply) { int win_rate_model(Value v, int ply) {
// The model captures only up to 240 plies, so limit input (and rescale) // The model only captures up to 240 plies, so limit the input and then rescale
double m = std::min(240, ply) / 64.0; double m = std::min(240, ply) / 64.0;
// Coefficients of a 3rd order polynomial fit based on fishtest data // The coefficients of a third-order polynomial fit is based on the fishtest data
// for two parameters needed to transform eval to the argument of a // for two parameters that need to transform eval to the argument of a logistic
// logistic function. // function.
double as[] = {-1.17202460e-01, 5.94729104e-01, 1.12065546e+01, 1.22606222e+02}; double as[] = {-1.17202460e-01, 5.94729104e-01, 1.12065546e+01, 1.22606222e+02};
double bs[] = {-1.79066759, 11.30759193, -17.43677612, 36.47147479}; double bs[] = {-1.79066759, 11.30759193, -17.43677612, 36.47147479};
double a = (((as[0] * m + as[1]) * m + as[2]) * m) + as[3]; double a = (((as[0] * m + as[1]) * m + as[2]) * m) + as[3];
double b = (((bs[0] * m + bs[1]) * m + bs[2]) * m) + bs[3]; double b = (((bs[0] * m + bs[1]) * m + bs[2]) * m) + bs[3];
// Transform eval to centipawns with limited range // Transform the eval to centipawns with limited range
double x = std::clamp(double(100 * v) / PawnValueEg, -2000.0, 2000.0); double x = std::clamp(double(100 * v) / PawnValueEg, -2000.0, 2000.0);
// Return win rate in per mille (rounded to nearest) // Return the win rate in per mille units rounded to the nearest value
return int(0.5 + 1000 / (1 + std::exp((a - x) / b))); return int(0.5 + 1000 / (1 + std::exp((a - x) / b)));
} }
} // namespace } // namespace
/// UCI::loop() waits for a command from stdin, parses it and calls the appropriate /// UCI::loop() waits for a command from the stdin, parses it and then calls the appropriate
/// function. Also intercepts EOF from stdin to ensure gracefully exiting if the /// function. It also intercepts an end-of-file (EOF) indication from the stdin to ensure a
/// GUI dies unexpectedly. When called with some command line arguments, e.g. to /// graceful exit if the GUI dies unexpectedly. When called with some command-line arguments,
/// run 'bench', once the command is executed the function returns immediately. /// like running 'bench', the function returns immediately after the command is executed.
/// In addition to the UCI ones, also some additional debug commands are supported. /// In addition to the UCI ones, some additional debug commands are also supported.
void UCI::loop(int argc, char* argv[]) { void UCI::loop(int argc, char* argv[]) {
@ -240,24 +240,24 @@ void UCI::loop(int argc, char* argv[]) {
cmd += std::string(argv[i]) + " "; cmd += std::string(argv[i]) + " ";
do { do {
if (argc == 1 && !getline(cin, cmd)) // Block here waiting for input or EOF if (argc == 1 && !getline(cin, cmd)) // Wait for an input or an end-of-file (EOF) indication
cmd = "quit"; cmd = "quit";
istringstream is(cmd); istringstream is(cmd);
token.clear(); // Avoid a stale if getline() returns empty or blank line token.clear(); // Avoid a stale if getline() returns nothing or a blank line
is >> skipws >> token; is >> skipws >> token;
if ( token == "quit" if ( token == "quit"
|| token == "stop") || token == "stop")
Threads.stop = true; Threads.stop = true;
// The GUI sends 'ponderhit' to tell us the user has played the expected move. // The GUI sends 'ponderhit' to tell that the user has played the expected move.
// So 'ponderhit' will be sent if we were told to ponder on the same move the // So, 'ponderhit' is sent if pondering was done on the same move that the user
// user has played. We should continue searching but switch from pondering to // has played. The search should continue, but should also switch from pondering
// normal search. // to the normal search.
else if (token == "ponderhit") else if (token == "ponderhit")
Threads.main()->ponder = false; // Switch to normal search Threads.main()->ponder = false; // Switch to the normal search
else if (token == "uci") else if (token == "uci")
sync_cout << "id name " << engine_info(true) sync_cout << "id name " << engine_info(true)
@ -270,8 +270,8 @@ void UCI::loop(int argc, char* argv[]) {
else if (token == "ucinewgame") Search::clear(); else if (token == "ucinewgame") Search::clear();
else if (token == "isready") sync_cout << "readyok" << sync_endl; else if (token == "isready") sync_cout << "readyok" << sync_endl;
// Additional custom non-UCI commands, mainly for debugging. // Add custom non-UCI commands, mainly for debugging purposes.
// Do not use these commands during a search! // These commands must not be used during a search!
else if (token == "flip") pos.flip(); else if (token == "flip") pos.flip();
else if (token == "bench") bench(pos, is, states); else if (token == "bench") bench(pos, is, states);
else if (token == "d") sync_cout << pos << sync_endl; else if (token == "d") sync_cout << pos << sync_endl;
@ -286,24 +286,24 @@ void UCI::loop(int argc, char* argv[]) {
Eval::NNUE::save_eval(filename); Eval::NNUE::save_eval(filename);
} }
else if (token == "--help" || token == "help" || token == "--license" || token == "license") else if (token == "--help" || token == "help" || token == "--license" || token == "license")
sync_cout << "\nStockfish is a powerful chess engine and free software licensed under the GNU GPLv3." sync_cout << "\nStockfish is a powerful chess engine for playing and analyzing."
"\nStockfish is normally used with a separate graphical user interface (GUI)." "\nIt is released as free software licensed under the GNU GPLv3 License."
"\nStockfish implements the universal chess interface (UCI) to exchange information." "\nStockfish is normally used with a graphical user interface (GUI) and implements"
"\nFor further information see https://github.com/official-stockfish/Stockfish#readme" "\nthe Universal Chess Interface (UCI) protocol to communicate with a GUI, an API, etc."
"\nor the corresponding README.md and Copying.txt files distributed with this program.\n" << sync_endl; "\nFor any further information, visit https://github.com/official-stockfish/Stockfish#readme"
"\nor read the corresponding README.md and Copying.txt files distributed along with this program.\n" << sync_endl;
else if (!token.empty() && token[0] != '#') else if (!token.empty() && token[0] != '#')
sync_cout << "Unknown command: '" << cmd << "'. Type help for more information." << sync_endl; sync_cout << "Unknown command: '" << cmd << "'. Type help for more information." << sync_endl;
} while (token != "quit" && argc == 1); // Command line args are one-shot } while (token != "quit" && argc == 1); // The command-line arguments are one-shot
} }
/// UCI::value() converts a Value to a string suitable for use with the UCI /// UCI::value() converts a Value to a string by adhering to the UCI protocol specification:
/// protocol specification:
/// ///
/// cp <x> The score from the engine's point of view in centipawns. /// cp <x> The score from the engine's point of view in centipawns.
/// mate <y> Mate in y moves, not plies. If the engine is getting mated /// mate <y> Mate in 'y' moves (not plies). If the engine is getting mated,
/// use negative values for y. /// uses negative values for 'y'.
string UCI::value(Value v) { string UCI::value(Value v) {
@ -320,8 +320,8 @@ string UCI::value(Value v) {
} }
/// UCI::wdl() report WDL statistics given an evaluation and a game ply, based on /// UCI::wdl() reports the win-draw-loss (WDL) statistics given an evaluation
/// data gathered for fishtest LTC games. /// and a game ply based on the data gathered for fishtest LTC games.
string UCI::wdl(Value v, int ply) { string UCI::wdl(Value v, int ply) {
@ -344,9 +344,9 @@ std::string UCI::square(Square s) {
/// UCI::move() converts a Move to a string in coordinate notation (g1f3, a7a8q). /// UCI::move() converts a Move to a string in coordinate notation (g1f3, a7a8q).
/// The only special case is castling, where we print in the e1g1 notation in /// The only special case is castling where the e1g1 notation is printed in
/// normal chess mode, and in e1h1 notation in chess960 mode. Internally all /// standard chess mode and in e1h1 notation it is printed in Chess960 mode.
/// castling moves are always encoded as 'king captures rook'. /// Internally, all castling moves are always encoded as 'king captures rook'.
string UCI::move(Move m, bool chess960) { string UCI::move(Move m, bool chess960) {
@ -376,8 +376,8 @@ string UCI::move(Move m, bool chess960) {
Move UCI::to_move(const Position& pos, string& str) { Move UCI::to_move(const Position& pos, string& str) {
if (str.length() == 5) // Junior could send promotion piece in uppercase if (str.length() == 5)
str[4] = char(tolower(str[4])); str[4] = char(tolower(str[4])); // The promotion piece character must be lowercased
for (const auto& m : MoveList<LEGAL>(pos)) for (const auto& m : MoveList<LEGAL>(pos))
if (str == UCI::move(m, pos.is_chess960())) if (str == UCI::move(m, pos.is_chess960()))

View file

@ -32,15 +32,15 @@ namespace UCI {
class Option; class Option;
/// Custom comparator because UCI options should be case insensitive /// Define a custom comparator, because the UCI options should be case-insensitive
struct CaseInsensitiveLess { struct CaseInsensitiveLess {
bool operator() (const std::string&, const std::string&) const; bool operator() (const std::string&, const std::string&) const;
}; };
/// Our options container is actually a std::map /// The options container is defined as a std::map
typedef std::map<std::string, Option, CaseInsensitiveLess> OptionsMap; typedef std::map<std::string, Option, CaseInsensitiveLess> OptionsMap;
/// Option class implements an option as defined by UCI protocol /// The Option class implements each option as specified by the UCI protocol
class Option { class Option {
typedef void (*OnChange)(const Option&); typedef void (*OnChange)(const Option&);