X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xboard2uci.c;h=4ddb72e048d9b53dba026c6d7352fa4c442bf14c;hb=learn;hp=fe0ded347f16365dcd7c90a37c57fe3b2f066839;hpb=ae338a820ef1c16d4399958613bbc0b908904b91;p=polyglot.git diff --git a/xboard2uci.c b/xboard2uci.c index fe0ded3..4ddb72e 100644 --- a/xboard2uci.c +++ b/xboard2uci.c @@ -21,6 +21,7 @@ #include "move.h" #include "move_do.h" #include "move_legal.h" +#include "move_gen.h" #include "option.h" #include "parse.h" #include "san.h" @@ -43,6 +44,7 @@ static const bool DelayPong = FALSE; typedef struct { int state; bool computer[ColourNb]; + bool playedAllMoves[ColourNb]; int exp_move; int hint_move; int resign_nb; @@ -54,6 +56,7 @@ typedef struct { bool has_feature_smp; bool has_feature_egt_nalimov; bool has_feature_egt_gaviota; + bool has_feature_egt_syzygy; bool analyse; bool computer; const char * name; @@ -148,6 +151,7 @@ void xboard2uci_init() { // This is a quick hack. XB->has_feature_egt_nalimov = (option_find(Uci->option,"NalimovPath")!=NULL); XB->has_feature_egt_gaviota = (option_find(Uci->option,"GaviotaTbPath")!=NULL); + XB->has_feature_egt_syzygy = (option_find(Uci->option,"SyzygyPath")!=NULL); XB->analyse = FALSE; XB->computer = FALSE; XB->name = NULL; @@ -176,6 +180,9 @@ void xboard2uci_init() { XB->node_rate = -1; } + +static list_t move_list[1]; + // xboard2uci_gui_step() void xboard2uci_gui_step(char string[]) { @@ -207,8 +214,50 @@ void xboard2uci_gui_step(char string[]) { if (option_get_bool(Option,"Book")) { game_get_board(Game,board); book_disp(board); + } else { // [HGM] without book, print all legal moves + int i, gen=!list_size(move_list); + game_get_board(Game,board); + if(gen) gen_legal_moves(move_list,board); + for(i=0; ivalue[i] = 0; + move_to_san(move_list->move[i],board,move_string,256); + printf(" %s%6s\n", move_list->value[i]? "* " : "", move_string); + } + // this is necessary by the xboard protocol + printf("\n"); } + } else if (match(string,"exclude *") || match(string,"option Polyglot exclude move=*")) { // [HGM] + + int i, all = !strcmp(Star[0], "all"), change=FALSE, cnt=0; + game_get_board(Game,board); + if(!list_size(move_list)) { + gen_legal_moves(move_list,board); + for(i=0; ivalue[i] = 0; + } + } + move = move_from_san(Star[0],board); + + for(i=0; imove[i] == move) + change |= !move_list->value[i], move_list->value[i] = 1; + cnt += !move_list->value[i]; + } + if(change && cnt) mess(); // do not relay to engine if no change or no moves left + + } else if (match(string,"include *")) { // [HGM] + + int i, all = !strcmp(Star[0], "all"), change = FALSE; + game_get_board(Game,board); + move = move_from_san(Star[0],board); + + for(i=0; imove[i] == move) + change |= move_list->value[i], move_list->value[i] = 0; + } + if(change) mess(); + } else if (match(string,"black")) { if (colour_is_black(game_turn(Game))) { @@ -230,6 +279,10 @@ void xboard2uci_gui_step(char string[]) { if(option_find(Uci->option,"UCI_DrawOffers")){ my_log("POLYGLOT draw from XB received"); uci_send_option(Uci,"DrawOffer","%s","draw");} + else if (option_get_bool(Option,"HandleDraws") && Uci->root_move_nb > 20) { // [HGM] PG draw handling + my_log("POLYGLOT draw from XB received"); + if (Uci->best_score <= -option_get_int(Option,"ContemptScore")) + gui_send(GUI,"offer draw");} } else if (match(string,"easy")) { XB->ponder = FALSE; @@ -321,12 +374,16 @@ void xboard2uci_gui_step(char string[]) { game_clear(Game); + move_list->size = 0; // [HGM] clear all exclude moves + if (XB->analyse) { State->computer[White] = FALSE; State->computer[Black] = FALSE; } else { State->computer[White] = FALSE; State->computer[Black] = TRUE; + State->playedAllMoves[White] = TRUE; // [HGM] + State->playedAllMoves[Black] = TRUE; } XB->new_hack = TRUE; @@ -334,6 +391,9 @@ void xboard2uci_gui_step(char string[]) { XB->depth_limit = FALSE; XB->node_rate=-1; + if (option_find(Uci->option,"UCI_PlayByNodes")) { + uci_send_option(Uci,"UCI_PlayByNodes","%d",0); + } XB->computer = FALSE; my_string_set(&XB->name,""); @@ -371,7 +431,12 @@ void xboard2uci_gui_step(char string[]) { gui_send(GUI,"pong %s",Star[0]); } } else if (match(string,"nps *")) { - + + if (Star[0] > 0 && option_find(Uci->option,"UCI_PlayByNodes")) { + + uci_send_option(Uci,"UCI_PlayByNodes","%d",Star[0]); + + } else // fake WB play-by-nodes mode XB->node_rate = atoi(Star[0]); } else if (match(string,"playother")) { @@ -528,6 +593,12 @@ void xboard2uci_gui_step(char string[]) { start_protected_command(); uci_send_option(Uci,"GaviotaTbPath","%s",path); end_protected_command(); + }else if(my_string_case_equal(type,"syzygy") && XB->has_feature_egt_syzygy){ + // updating SyzygyPath + my_log("POLYGLOT setting the Syzygy path to %s\n",path); + start_protected_command(); + uci_send_option(Uci,"SyzygyPath","%s",path); + end_protected_command(); }else{ // refuse gui_send(GUI,"Error (unsupported table base format): %s",string); @@ -540,17 +611,22 @@ void xboard2uci_gui_step(char string[]) { if(memory>=1){ // updating the available memory option_t *opt; + int h; my_log("POLYGLOT setting the amount of memory to %dMb\n",memory); + egt_cache=0; if(XB->has_feature_egt_nalimov && (opt=option_find(Uci->option,"NalimovCache"))){ - egt_cache=atoi(opt->value); - }else if(XB->has_feature_egt_gaviota && + h=atoi(opt->value); + if(h>egt_cache)egt_cache=h; + } + if(XB->has_feature_egt_gaviota && (opt=option_find(Uci->option,"GaviotaTbCache"))){ - egt_cache=atoi(opt->value); - }else{ - egt_cache=0; + h=atoi(opt->value); + if(h>egt_cache)egt_cache=h; } my_log("POLYGLOT EGTB Cache is %dMb\n",egt_cache); real_memory=memory-egt_cache; + opt=option_find(Uci->option,"Hash"); + if(opt && real_memory > atoi(opt->max)) real_memory = atoi(opt->max); // [HGM] top off if(real_memory>0){ start_protected_command(); uci_send_option(Uci,"Hash", "%d", real_memory); @@ -572,6 +648,8 @@ void xboard2uci_gui_step(char string[]) { if (!game_init(Game,Star[0])) my_fatal("xboard_step(): bad FEN \"%s\"\n",Star[0]); + move_list->size = 0; // [HGM] clear all exclude moves + State->computer[White] = FALSE; State->computer[Black] = FALSE; @@ -593,6 +671,8 @@ void xboard2uci_gui_step(char string[]) { } else if (match(string,"undo")) { + move_list->size = 0; // [HGM] clear all exclude moves + if (game_pos(Game) >= 1) { game_goto(Game,game_pos(Game)-1); @@ -607,6 +687,8 @@ void xboard2uci_gui_step(char string[]) { } else if (match(string,"usermove *")) { + move_list->size = 0; // [HGM] clear all exclude moves + game_get_board(Game,board); move = move_from_san(Star[0],board); @@ -616,6 +698,9 @@ void xboard2uci_gui_step(char string[]) { ASSERT(!XB->result); XB->result = FALSE; + // [HGM] externally supplied move means we did not fully play the current stm + State->playedAllMoves[colour_is_white(game_turn(Game)) ? White : Black] = FALSE; + move_step(move); no_mess(move); @@ -846,6 +931,19 @@ void format_xboard_option_line(char * option_line, option_t *opt){ } } +// disarm() // [HGM] cleanse a string of offending double-quotes + +static char*disarm(const char *s){ + static char buf[25]; + char *p = buf, *q; + strncpy(buf, s, 24); + q = buf + strlen(buf) - 1; + while(*q == '"') *q-- = '\0'; // strip trailing quotes + while(*p == '"') p++; // strip leading quotes + while((q = strchr(p, '"'))) *q = '\''; // replace internal quotes + return p; +} + // send_xboard_options() static void send_xboard_options(){ @@ -856,11 +954,12 @@ static void send_xboard_options(){ gui_send(GUI,"feature done=0"); gui_send(GUI,"feature analyze=1"); + gui_send(GUI,"feature exclude=1"); gui_send(GUI,"feature colors=0"); gui_send(GUI,"feature draw=1"); gui_send(GUI,"feature ics=1"); gui_send(GUI,"feature myname=\"%s\"", - option_get_string(Option,"EngineName")); + disarm(option_get_string(Option,"EngineName"))); gui_send(GUI,"feature name=1"); gui_send(GUI,"feature pause=0"); gui_send(GUI,"feature ping=1"); @@ -894,8 +993,15 @@ static void send_xboard_options(){ if(tbs>0){ strncat(egtfeature,",",StringSize-strlen(egtfeature)); } + tbs++; strncat(egtfeature,"gaviota",StringSize-strlen(egtfeature)); } + if (XB->has_feature_egt_syzygy){ + if(tbs>0){ + strncat(egtfeature,",",StringSize-strlen(egtfeature)); + } + strncat(egtfeature,"syzygy",StringSize-strlen(egtfeature)); + } strncat(egtfeature,"\"",StringSize-strlen(egtfeature)); egtfeature[StringSize-1]='\0'; gui_send(GUI,egtfeature); @@ -924,10 +1030,12 @@ void xboard2uci_send_options(){ if(my_string_case_equal(opt->name,"UCI_ShredderbasesPath")) continue; if(my_string_case_equal(opt->name,"UCI_SetPositionValue")) continue; if(my_string_case_equal(opt->name,"UCI_DrawOffers")) continue; + if(my_string_case_equal(opt->name,"UCI_PlayByNodes")) continue; if(my_string_case_equal(opt->name,"Ponder")) continue; if(my_string_case_equal(opt->name,"Hash")) continue; if(my_string_case_equal(opt->name,"NalimovPath")) continue; if(my_string_case_equal(opt->name,"GaviotaTbPath")) continue; + if(my_string_case_equal(opt->name,"SyzygyPath")) continue; if((name=uci_thread_option(Uci))!=NULL && my_string_case_equal(opt->name,name)) continue; format_xboard_option_line(option_line,opt); @@ -936,6 +1044,8 @@ void xboard2uci_send_options(){ } + gui_send(GUI,"feature option=\"Polyglot exclude move -string \""); + option_start_iter(Option); while((opt=option_next(Option))){ if(opt->mode &XBOARD){ @@ -995,8 +1105,10 @@ static void comp_move(int move) { my_log("POLYGLOT %d move%s with resign score\n",State->resign_nb,(State->resign_nb>1)?"s":""); if (State->resign_nb >= option_get_int(Option,"ResignMoves")) { - my_log("POLYGLOT *** RESIGN ***\n"); - gui_send(GUI,"resign"); + if (!option_get_bool(Option,"QueenNeverResigns") || !board_has_queen(board, board->turn)) { // [HGM] suppress resignig with Queen + my_log("POLYGLOT *** RESIGN ***\n"); + gui_send(GUI,"resign"); + } } } else { @@ -1334,9 +1446,17 @@ static void search_update() { " nodes %.0f", XB->time_max*((double)XB->node_rate)); }else{ + double computed_time; + double st_fudge; + st_fudge=(double) option_get_int(Option,"STFudge"); + my_log("POLYGLOT Giving engine %.0fmsec extra time.\n",st_fudge); + computed_time=XB->time_max*1000.0-st_fudge; + if(computed_time< 1.0){ + computed_time=1.0; + } engine_send_queue(Engine, " movetime %.0f", - XB->time_max*1000.0); + computed_time); } } else { @@ -1392,8 +1512,23 @@ static void search_update() { engine_send(Engine,""); // newline } else if (State->state == ANALYSE) { - - engine_send(Engine,"go infinite"); + int i; + char move_string[256]; + + engine_send_queue(Engine,"go infinite"); + + if(list_size(move_list)) { + board_t board[1]; + game_get_board(Game,board); + engine_send_queue(Engine," searchmoves"); + for(i=0; ivalue[i]) { + move_to_can(move_list->move[i],board,move_string,256); + engine_send_queue(Engine," %s",move_string); + } + } + } + engine_send(Engine,""); // newline } else { @@ -1583,12 +1718,16 @@ static void send_info() { }else{ min_depth=1; } + if(!strncmp(Uci->info, "xboard ", 7)) gui_send(GUI,"%s",Uci->info+7); else // kludge to allow UCI engines to use WB protocol gui_send(GUI,"%d %+d %.0f "S64_FORMAT" %s",Uci->best_depth>min_depth?Uci->best_depth:min_depth, - 0,0,0.0,0,Uci->info); + 0,0.0,U64(0),Uci->info); } // send_pv() +//define EXT_INFO_FORMAT "{%d,%.0f,"S64_FORMAT"} " +#define EXT_INFO_FORMAT " %2d %4.0f "S64_FORMAT"\t" + static void send_pv() { char pv_string[StringSize]; @@ -1610,8 +1749,11 @@ static void send_pv() { if(Uci->depth==-1) //hack to clear the engine output window gui_send(GUI,"%d %+d %.0f "S64_FORMAT" ",0,report_best_score(),Uci->time*100.0,Uci->node_nb); - - gui_send(GUI,"%d %+d %.0f "S64_FORMAT" %s",Uci->best_depth,report_best_score(),Uci->time*100.0,Uci->node_nb,pv_string); + if(option_get_bool(Option,"ShowTbHits")) + gui_send(GUI,"%d %+d %.0f "S64_FORMAT EXT_INFO_FORMAT"%s%c",Uci->best_depth,report_best_score(), + Uci->time*100.0,Uci->node_nb,Uci->sel_depth,Uci->speed/1e3,Uci->tbhit_nb,pv_string,Uci->bound_type); + else + gui_send(GUI,"%d %+d %.0f "S64_FORMAT" %s%c",Uci->best_depth,report_best_score(),Uci->time*100.0,Uci->node_nb,pv_string,Uci->bound_type); } else if (State->state == PONDER && option_get_bool(Option,"ShowPonder")) { @@ -1622,7 +1764,12 @@ static void send_pv() { if (move != MoveNone && move_is_legal(move,board)) { move_to_san(move,board,move_string,256); line_to_san(Uci->best_pv,Uci->board,pv_string,StringSize); - gui_send(GUI,"%d %+d %.0f "S64_FORMAT" (%s) %s",Uci->best_depth,report_best_score(),Uci->time*100.0,Uci->node_nb,move_string,pv_string); + if(option_get_bool(Option,"ShowTbHits")) + gui_send(GUI,"%d %+d %.0f "S64_FORMAT EXT_INFO_FORMAT"(%s) %s%c",Uci->best_depth,report_best_score(), + Uci->time*100.0,Uci->node_nb,Uci->sel_depth,Uci->speed/1e3,Uci->tbhit_nb,move_string,pv_string,Uci->bound_type); + else + gui_send(GUI,"%d %+d %.0f "S64_FORMAT" (%s) %s%c",Uci->best_depth,report_best_score(), + Uci->time*100.0,Uci->node_nb,move_string,pv_string,Uci->bound_type); } } } @@ -1691,20 +1838,20 @@ static void learn(int result) { ASSERT(result>=-1&&result<=+1); ASSERT(XB->result); - ASSERT(State->computer[White]||State->computer[Black]); +// ASSERT(State->computer[White]||State->computer[Black]); // init pos = 0; - if (FALSE) { - } else if (State->computer[White]) { + // [HGM] does not account for the hypothetical possibility we played both sides! + if (State->playedAllMoves[White]) { pos = 0; - } else if (State->computer[Black]) { + } else if (State->playedAllMoves[Black]) { pos = 1; result = -result; } else { - my_fatal("learn(): unknown side\n"); + return; // [HGM] if we did not play all moves for some side, do not learn, but don't make a fuss! } if (FALSE) {