From 26d4bd0e336dd729589dbec58ad12e3e50a7e2b6 Mon Sep 17 00:00:00 2001 From: H.G. Muller Date: Fri, 13 Sep 2013 19:37:59 +0200 Subject: [PATCH] Make multi-PV mode accessible from XBoard protocol Multi-PV mode uses another routine for printing the PVs, which had to be adapted. In native mode Bonanza repeats all PVs all the time; in XBoard mode it suppresses printing of all but the latest. Option features were added to set number of PVs and margin. --- Makefile | 2 +- proce.c | 29 +++++++++++++++++++++-------- searchr.c | 57 ++++++++++++++++++++++++++++++++++++++------------------- 3 files changed, 60 insertions(+), 28 deletions(-) diff --git a/Makefile b/Makefile index 9eed265..888eb3c 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ OBJS =data.o main.o io.o proce.o utility.o ini.o attack.o book.o makemove.o \ # -DDFPN build the DFPN worker of mate-problems server. # -DDFPN_CLIENT enables the client-mode of mate-problem server. -OPT =-DNDEBUG -DMINIMUM -DHAVE_SSE4 -msse4.1 -DDFPN -DTLP -DDFPN_CLIENT -DINANIWA_SHIFT -DMNJ_LAN -DCSA_LAN -DXBOARD +OPT =-DNDEBUG -DMINIMUM -DHAVE_SSE4 -msse4.1 -DDFPN -DTLP -DDFPN_CLIENT -DINANIWA_SHIFT -DMNJ_LAN -DCSA_LAN -DXBOARD -DMPV help: @echo "try targets as:" diff --git a/proce.c b/proce.c index 1aab235..db64ef3 100644 --- a/proce.c +++ b/proce.c @@ -58,7 +58,7 @@ static int CONV cmd_thread( char **lasts ); #endif #if defined(MPV) -static int CONV cmd_mpv( char **lasts ); +static int CONV cmd_mpv( tree_t * restrict ptree, char **lasts ); #endif #if defined(DFPN) @@ -160,8 +160,14 @@ proce_xboard(char *line, const char *command, tree_t * restrict ptree) sscanf(line + strlen(command) + 1, "%d", &value); Out("# command = '%s'\n", line); if(0) ; - IF("protover") { Out("feature variants=\"shogi\" usermove=1 myname=\"Bonanza " BNZ_VER - "\" memory=1 smp=1 debug=1 colors=0 setboard=1 ping=1 done=1\n"); } + IF("protover") { +#if defined(MPV) + Out("feature option=\"MultiPV -spin 1 1 100\"\n"); + Out("feature option=\"centi-Pawn margin -spin 200 0 25000\"\n"); +#endif + Out("feature variants=\"shogi\" usermove=1 myname=\"Bonanza " BNZ_VER + "\" memory=1 smp=1 debug=1 colors=0 setboard=1 ping=1 done=1\n"); + } IF("new") { forceMode = plyNr = 0; SetTimes(); return 0; } IF("easy") { strcpy(line, "ponder off"); return 0; } IF("hard") { strcpy(line, "ponder on"); return 0; } @@ -180,7 +186,10 @@ Out("# command = '%s'\n", line); IF("exit") { return 0; } IF("variant") { /* ignore, since it must be Shogi */; } IF("setboard") { ; } - IF("option") { ; } + IF("option") { + if(sscanf(line+7, "MultiPV=%d", &value) == 1) { sprintf(line, "mpv num %d", value); return 0; } + if(sscanf(line+7, "centi-Pawn margin=%d", &value) == 1) { sprintf(line, "mpv width %d", value); return 0; } + } IF("level") { int min, sec; float fsec=0.; if(sscanf(line+6, "%d %d:%d %f", &movesPerSession, &min, &sec, &fsec) != 4) sscanf(line+6, "%d %d %f", &movesPerSession, &min, &fsec); @@ -240,6 +249,9 @@ static int CONV proce_cui( tree_t * restrict ptree ) if ( ! strcmp( token, "exit" ) ) { return cmd_exit(); } // [HGM] analyze if ( ! strcmp( token, "move" ) ) { return cmd_move( ptree, &last ); } if ( ! strcmp( token, "undo" ) ) { return cmd_undo( ptree ); } // [HGM] undo +#if defined(MPV) + if ( ! strcmp( token, "mpv" ) ) { return cmd_mpv( ptree, &last ); } +#endif analyze_mode = 0; // [HGM] analyze: all other commands terminate analysis if ( is_move( token ) ) { return cmd_usrmove( ptree, token, &last ); } if ( ! strcmp( token, "s" ) ) { return cmd_move_now(); } @@ -268,9 +280,6 @@ static int CONV proce_cui( tree_t * restrict ptree ) #if defined(MNJ_LAN) if ( ! strcmp( token, "mnj" ) ) { return cmd_mnj( &last ); } #endif -#if defined(MPV) - if ( ! strcmp( token, "mpv" ) ) { return cmd_mpv( &last ); } -#endif #if defined(DFPN) if ( ! strcmp( token, "dfpn" ) ) { return cmd_dfpn( ptree, &last ); } #endif @@ -1874,7 +1883,7 @@ static int CONV cmd_learn( tree_t * restrict ptree, char **lasts ) #if defined(MPV) -static int CONV cmd_mpv( char **lasts ) +static int CONV cmd_mpv( tree_t * restrict ptree, char **lasts ) { const char *str = strtok_r( NULL, str_delimiters, lasts ); char *ptr; @@ -1904,6 +1913,8 @@ static int CONV cmd_mpv( char **lasts ) mpv_num = (int)l; + if ( analyze_mode ) return do_analyze ( ptree ); // [HGM] analyze: analysis should continue changing num + return 1; } else if ( ! strcmp( str, "width" ) ) @@ -1925,6 +1936,8 @@ static int CONV cmd_mpv( char **lasts ) mpv_width = (int)l; + if ( analyze_mode ) return do_analyze ( ptree ); // [HGM] analyze: analysis should continue after changing width + return 1; } diff --git a/searchr.c b/searchr.c index 216967d..6d2af78 100644 --- a/searchr.c +++ b/searchr.c @@ -12,8 +12,7 @@ static int CONV mpv_set_bound( int alpha ); static int CONV mpv_find_min( int *pnum ); static int CONV mpv_add_result( tree_t * restrict ptree, int value ); static void CONV mpv_sub_result( unsigned int move ); -static void CONV mpv_out( tree_t * restrict ptree, int turn, - unsigned int time ); +static void CONV mpv_out( tree_t * restrict ptree, int turn, unsigned int time, int newest ); #endif #if defined(NO_STDOUT) && defined(NO_LOGGING) @@ -315,6 +314,21 @@ searchr( tree_t * restrict ptree, int alpha, int beta, int turn, int depth ) } +#ifdef XBOARD +void CONV +out_xboard_move( int move, int tt ) +{ + int from = I2From(move), to = I2To(move); + char inPromoZone = tt > 0 ? from >= 6*9 || to >= 6*9 : to < 3*9|| from < 3*9; + if(from >= nsquare) + Out(" %c@%c%c", "PLNSGBR"[From2Drop(from)-1], 'a'+to%9, '9'-to/9); + else + Out(" %c%c%c%c%s", 'a'+from%9, '9'-from/9, 'a'+to%9, '9'-to/9, + inPromoZone ? I2IsPromote(move) ? "+" : "=" : ""); +} +#endif + + void CONV out_pv( tree_t * restrict ptree, int value, int turn, unsigned int time ) { @@ -370,13 +384,7 @@ out_pv( tree_t * restrict ptree, int value, int turn, unsigned int time ) { #ifdef XBOARD if(xboard_mode && is_out) { // print PV move in WB format - int move = ptree->pv[0].a[ply], from = I2From(move), to = I2To(move); - char inPromoZone = tt > 0 ? from >= 6*9 || to >= 6*9 : to < 3*9|| from < 3*9; - if(from >= nsquare) - Out(" %c@%c%c", "PLNSGBR"[From2Drop(from)-1], 'a'+to%9, '9'-to/9); - else - Out(" %c%c%c%c%s", 'a'+from%9, '9'-from/9, 'a'+to%9, '9'-to/9, - inPromoZone ? I2IsPromote(move) ? "+" : "=" : ""); + out_xboard_move( ptree->pv[0].a[ply], tt ); } else #endif if ( is_out ) @@ -427,13 +435,7 @@ out_pv( tree_t * restrict ptree, int value, int turn, unsigned int time ) #ifdef XBOARD if(xboard_mode && is_out) { // print PV move in WB format - int move = ptree->pv[0].a[ply], from = I2From(move), to = I2To(move); - char inPromoZone = tt > 0 ? from >= 6*9 || to >= 6*9 : to < 3*9|| from < 3*9; - if(from >= nsquare) - Out(" %c@%c%c", "PLNSGBR"[From2Drop(from)-1], 'a'+to%9, '9'-to/9); - else - Out(" %c%c%c%c%s", 'a'+from%9, '9'-from/9, 'a'+to%9, '9'-to/9, - inPromoZone ? I2IsPromote(move) ? "+" : "=" : ""); + out_xboard_move( ptree->pv[0].a[ply], tt ); } else #endif if ( is_out ) @@ -606,7 +608,7 @@ next_root_move( tree_t * restrict ptree, int turn ) #if defined(MPV) static void CONV -mpv_out( tree_t * restrict ptree, int turn, unsigned int time ) +mpv_out( tree_t * restrict ptree, int turn, unsigned int time, int newest ) { int mpv_out, ipv, best; @@ -643,12 +645,23 @@ mpv_out( tree_t * restrict ptree, int turn, unsigned int time ) str = str_time_symple( time ); ply = mpv_pv[ipv].depth; +#ifdef XBOARD + if(xboard_mode) { + if(ipv != newest) continue; // skip all but the newest, to prevent duplicates + Out("%2d %6d %6d %8d ", ply, value, time/10, 1); + } else +#endif if ( ! ipv ) { Out( "o%2d %6s %7.2f ", ply, str, dvalue ); } else { Out( " %2d %7.2f ", ply, dvalue ); } } for ( ply = 1; ply <= mpv_pv[ipv].length; ply++ ) { +#ifdef XBOARD + if(xboard_mode && is_out) { // print PV move in WB format + out_xboard_move( mpv_pv[ipv].a[ply], tt ); + } else +#endif if ( is_out ) { if ( ply > 1 && ! ( (ply-1) % 5 ) ) @@ -688,6 +701,11 @@ mpv_out( tree_t * restrict ptree, int turn, unsigned int time ) if ( mpv_pv[ipv].a[i] == mpv_pv[ipv].a[ply] ) { goto rep_esc; } +#ifdef XBOARD + if(xboard_mode && is_out) { // print PV move in WB format + out_xboard_move( mpv_pv[ipv].a[ply], tt ); + } else +#endif if ( is_out ) { if ( ply > 1 && ! ( (ply-1) % 5 ) ) @@ -780,7 +798,7 @@ mpv_add_result( tree_t * restrict ptree, int value ) { pv_t pv_tmp, pv; unsigned int time; - int i, vmin, num; + int i, vmin, num, new_pv; vmin = mpv_find_min( &num ); assert( num <= mpv_num ); @@ -825,6 +843,7 @@ mpv_add_result( tree_t * restrict ptree, int value ) pv = ptree->pv[1]; pv.a[0] = (unsigned int)(value+32768); + new_pv = i; // [HGM] xboard: remember which is the new one, so we can print only that do { assert( i < mpv_num*2 ); assert( i < root_nmove*2 ); @@ -836,7 +855,7 @@ mpv_add_result( tree_t * restrict ptree, int value ) if ( get_elapsed( &time ) < 0 ) { return -1; } - mpv_out( ptree, root_turn, time - time_start ); + mpv_out( ptree, root_turn, time - time_start, new_pv ); return 1; } -- 1.7.0.4