mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 00:33:09 +00:00
Use a string stream in UCIInputParser
Use a std::istringstream instead of an home grown string tokenizer code. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
b8e487ff9c
commit
d22aeb1cc0
1 changed files with 43 additions and 49 deletions
92
src/uci.cpp
92
src/uci.cpp
|
@ -22,6 +22,7 @@
|
||||||
////
|
////
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "book.h"
|
#include "book.h"
|
||||||
|
@ -43,12 +44,11 @@
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// UCIInputParser is a class for parsing UCI input. The class is
|
// UCIInputParser is a class for parsing UCI input. The class is
|
||||||
// very simple, and basically just consist of a constant input
|
// very simple, and basically just consist of a string stream
|
||||||
// string and a current location in the string. There are methods
|
// built on a given input string. There are methods for checking
|
||||||
// for checking if we are at the end of the line, for getting the
|
// if we are at the end of the line, for getting the next token
|
||||||
// next token (defined as any whitespace-delimited sequence of
|
// (defined as any whitespace-delimited sequence of characters),
|
||||||
// characters), and for getting the rest of the line as a single
|
// and for getting the rest of the line as a single string.
|
||||||
// string.
|
|
||||||
|
|
||||||
class UCIInputParser {
|
class UCIInputParser {
|
||||||
|
|
||||||
|
@ -59,10 +59,7 @@ namespace {
|
||||||
bool at_end_of_line();
|
bool at_end_of_line();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::string &inputLine;
|
std::istringstream inputLineStream;
|
||||||
int length, currentIndex;
|
|
||||||
|
|
||||||
void skip_whitespace();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -109,19 +106,7 @@ namespace {
|
||||||
// Constructor for the UCIInputParser class. The constructor takes a
|
// Constructor for the UCIInputParser class. The constructor takes a
|
||||||
// text string containing a single UCI command as input.
|
// text string containing a single UCI command as input.
|
||||||
|
|
||||||
UCIInputParser::UCIInputParser(const std::string &line) : inputLine(line) {
|
UCIInputParser::UCIInputParser(const std::string &line) : inputLineStream(line) { }
|
||||||
this->currentIndex = 0;
|
|
||||||
this->length = line.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// UCIInputParser::skip_whitspace() skips any number of whitespace
|
|
||||||
// characters from the current location in an input string.
|
|
||||||
|
|
||||||
void UCIInputParser::skip_whitespace() {
|
|
||||||
while(isspace(std::char_traits<char>::to_int_type(this->inputLine[this->currentIndex])))
|
|
||||||
this->currentIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// UCIInputParser::get_next_token() gets the next token in an UCI
|
// UCIInputParser::get_next_token() gets the next token in an UCI
|
||||||
|
@ -129,18 +114,12 @@ namespace {
|
||||||
// whitespace-delimited sequence of characters.
|
// whitespace-delimited sequence of characters.
|
||||||
|
|
||||||
std::string UCIInputParser::get_next_token() {
|
std::string UCIInputParser::get_next_token() {
|
||||||
int i, j;
|
|
||||||
|
|
||||||
this->skip_whitespace();
|
std::string token;
|
||||||
for(i = j = this->currentIndex;
|
|
||||||
j < this->length && !isspace(this->inputLine[j]);
|
|
||||||
j++);
|
|
||||||
this->currentIndex = j;
|
|
||||||
this->skip_whitespace();
|
|
||||||
|
|
||||||
std::string str = this->inputLine.substr(i, j - i);
|
inputLineStream >> token; // operator >> skips any whitespace
|
||||||
|
|
||||||
return str;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,8 +127,12 @@ namespace {
|
||||||
// line (from the current location) as a single string.
|
// line (from the current location) as a single string.
|
||||||
|
|
||||||
std::string UCIInputParser::get_rest_of_line() {
|
std::string UCIInputParser::get_rest_of_line() {
|
||||||
this->skip_whitespace();
|
|
||||||
return this->inputLine.substr(this->currentIndex, this->length);
|
std::string tail;
|
||||||
|
|
||||||
|
std::getline(inputLineStream, tail);
|
||||||
|
|
||||||
|
return tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -158,7 +141,8 @@ namespace {
|
||||||
// parsed.
|
// parsed.
|
||||||
|
|
||||||
bool UCIInputParser::at_end_of_line() {
|
bool UCIInputParser::at_end_of_line() {
|
||||||
return this->currentIndex == this->length;
|
|
||||||
|
return inputLineStream.eof();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -174,8 +158,12 @@ namespace {
|
||||||
// unexpectedly.
|
// unexpectedly.
|
||||||
|
|
||||||
void wait_for_command() {
|
void wait_for_command() {
|
||||||
|
|
||||||
std::string command;
|
std::string command;
|
||||||
if(!std::getline(std::cin, command)) command = "quit";
|
|
||||||
|
if (!std::getline(std::cin, command))
|
||||||
|
command = "quit";
|
||||||
|
|
||||||
handle_command(command);
|
handle_command(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,45 +174,46 @@ namespace {
|
||||||
// commands, the function also supports a few debug commands.
|
// commands, the function also supports a few debug commands.
|
||||||
|
|
||||||
void handle_command(const std::string &command) {
|
void handle_command(const std::string &command) {
|
||||||
UCIInputParser uip(command);
|
|
||||||
std::string s = uip.get_next_token();
|
|
||||||
|
|
||||||
if(s == "quit") {
|
UCIInputParser uip(command);
|
||||||
|
std::string token = uip.get_next_token();
|
||||||
|
|
||||||
|
if(token == "quit") {
|
||||||
OpeningBook.close();
|
OpeningBook.close();
|
||||||
stop_threads();
|
stop_threads();
|
||||||
quit_eval();
|
quit_eval();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
else if(s == "uci") {
|
else if(token == "uci") {
|
||||||
std::cout << "id name " << engine_name() << std::endl;
|
std::cout << "id name " << engine_name() << std::endl;
|
||||||
std::cout << "id author Tord Romstad" << std::endl;
|
std::cout << "id author Tord Romstad" << std::endl;
|
||||||
print_uci_options();
|
print_uci_options();
|
||||||
std::cout << "uciok" << std::endl;
|
std::cout << "uciok" << std::endl;
|
||||||
}
|
}
|
||||||
else if(s == "ucinewgame") {
|
else if(token == "ucinewgame") {
|
||||||
TT.clear();
|
TT.clear();
|
||||||
Position::init_piece_square_tables();
|
Position::init_piece_square_tables();
|
||||||
RootPosition.from_fen(StartPosition);
|
RootPosition.from_fen(StartPosition);
|
||||||
}
|
}
|
||||||
else if(s == "isready")
|
else if(token == "isready")
|
||||||
std::cout << "readyok" << std::endl;
|
std::cout << "readyok" << std::endl;
|
||||||
else if(s == "position")
|
else if(token == "position")
|
||||||
set_position(uip);
|
set_position(uip);
|
||||||
else if(s == "setoption")
|
else if(token == "setoption")
|
||||||
set_option(uip);
|
set_option(uip);
|
||||||
else if(s == "go")
|
else if(token == "go")
|
||||||
go(uip);
|
go(uip);
|
||||||
|
|
||||||
// The remaining commands are for debugging purposes only.
|
// The remaining commands are for debugging purposes only.
|
||||||
// Perhaps they should be removed later in order to reduce the
|
// Perhaps they should be removed later in order to reduce the
|
||||||
// size of the program binary.
|
// size of the program binary.
|
||||||
else if(s == "d")
|
else if(token == "d")
|
||||||
RootPosition.print();
|
RootPosition.print();
|
||||||
else if(s == "flip") {
|
else if(token == "flip") {
|
||||||
Position p(RootPosition);
|
Position p(RootPosition);
|
||||||
RootPosition.flipped_copy(p);
|
RootPosition.flipped_copy(p);
|
||||||
}
|
}
|
||||||
else if(s == "eval") {
|
else if(token == "eval") {
|
||||||
EvalInfo ei;
|
EvalInfo ei;
|
||||||
std::cout << "Incremental mg: " << RootPosition.mg_value()
|
std::cout << "Incremental mg: " << RootPosition.mg_value()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
@ -234,7 +223,7 @@ namespace {
|
||||||
<< evaluate(RootPosition, ei, 0)
|
<< evaluate(RootPosition, ei, 0)
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
else if(s == "key") {
|
else if(token == "key") {
|
||||||
std::cout << "key: " << RootPosition.get_key()
|
std::cout << "key: " << RootPosition.get_key()
|
||||||
<< " material key: " << RootPosition.get_material_key()
|
<< " material key: " << RootPosition.get_material_key()
|
||||||
<< " pawn key: " << RootPosition.get_pawn_key()
|
<< " pawn key: " << RootPosition.get_pawn_key()
|
||||||
|
@ -256,6 +245,7 @@ namespace {
|
||||||
// or "fen", if the input is well-formed).
|
// or "fen", if the input is well-formed).
|
||||||
|
|
||||||
void set_position(UCIInputParser &uip) {
|
void set_position(UCIInputParser &uip) {
|
||||||
|
|
||||||
std::string token;
|
std::string token;
|
||||||
|
|
||||||
token = uip.get_next_token();
|
token = uip.get_next_token();
|
||||||
|
@ -296,7 +286,9 @@ namespace {
|
||||||
// the input is well-formed).
|
// the input is well-formed).
|
||||||
|
|
||||||
void set_option(UCIInputParser &uip) {
|
void set_option(UCIInputParser &uip) {
|
||||||
|
|
||||||
std::string token;
|
std::string token;
|
||||||
|
|
||||||
if(!uip.at_end_of_line()) {
|
if(!uip.at_end_of_line()) {
|
||||||
token = uip.get_next_token();
|
token = uip.get_next_token();
|
||||||
if(token == "name" && !uip.at_end_of_line()) {
|
if(token == "name" && !uip.at_end_of_line()) {
|
||||||
|
@ -323,7 +315,9 @@ namespace {
|
||||||
// parameters.
|
// parameters.
|
||||||
|
|
||||||
void go(UCIInputParser &uip) {
|
void go(UCIInputParser &uip) {
|
||||||
|
|
||||||
std::string token;
|
std::string token;
|
||||||
|
|
||||||
int time[2] = {0, 0}, inc[2] = {0, 0}, movesToGo = 0, depth = 0, nodes = 0;
|
int time[2] = {0, 0}, inc[2] = {0, 0}, movesToGo = 0, depth = 0, nodes = 0;
|
||||||
int moveTime = 0;
|
int moveTime = 0;
|
||||||
bool infinite = false, ponder = false;
|
bool infinite = false, ponder = false;
|
||||||
|
|
Loading…
Add table
Reference in a new issue