From 796705fb0dd6391c4d0ad8a637eeefa405425bb0 Mon Sep 17 00:00:00 2001 From: H.G. Muller Date: Sat, 14 Sep 2013 13:54:23 +0200 Subject: [PATCH] Implement exclude-moves feature The WinBoard include and exclude commands are implemented to maintain an exclude_list of moves, which is then used during analyze mode in stead of the restraint.dat file to exclude root moves. The exclude_list contains moves in their internal encoding, which is now calculated as a side effect of the xboard -> CSA move conversion. --- proce.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++----------- root.c | 7 +++++++ shogi.h | 2 ++ 3 files changed, 57 insertions(+), 11 deletions(-) diff --git a/proce.c b/proce.c index cfeabe1..50eae57 100644 --- a/proce.c +++ b/proce.c @@ -96,6 +96,7 @@ procedure( tree_t * restrict ptree ) char *start_pos, start_data[512]; // [HGM] undo: for remembering start position int move_list[1024], move_ptr; char analyze_mode; +int exclude_list[MAX_LEGAL_MOVES], all_moves[MAX_LEGAL_MOVES]; #ifdef XBOARD #define IF(X) else if(!strcmp(command, X)) @@ -103,11 +104,11 @@ char analyze_mode; int myTime, hisTime, movesPerSession, inc, plyNr; char xboard_mode; -void -xboard_to_CSA( tree_t * restrict ptree, char *in, char *out ) +int +xboard_to_CSA( tree_t * restrict ptree, char *in, char *out, int status ) { char fromX=in[0], fromY=in[1], toX=in[2], toY=in[3], promo=in[4]; - int piece=0; + int piece=0, bonanza_move=0; if(fromY == '@') { // drop (contains all info needed to convert it) if(fromX >= 'a') fromX += 'A' - 'a'; switch(fromX) { // encode piece @@ -119,21 +120,23 @@ xboard_to_CSA( tree_t * restrict ptree, char *in, char *out ) case 'B': piece = bishop; break; case 'R': piece = rook; break; } + bonanza_move = Drop2Move(piece) | To2Move( ('9' - toY)*9 + (toX - 'a') ); sprintf(out, "00%c%c%s", 'a'+'9'-toX, '1'+'9'-toY, astr_table_piece[piece]); } else { // board move (need to figure out moved piece) int from = ('9' - fromY)*9 + (fromX - 'a'); int flag = (promo == '+' ? FLAG_PROMO : 0); piece = abs( BOARD[from] ); // this only works when not searching! printf("# piece from board: %d\n", piece);fflush(stdout); - if( game_status & ( flag_pondering | flag_puzzling | flag_thinking ) ) { - int i, to = ('9' - toY)*9 + (toX - 'a'); + if( status & ( flag_pondering | flag_puzzling | flag_thinking ) ) { + int i, to = ('9' - toY)*9 + (toX - 'a'), l = (status == (flag_pondering | flag_thinking)); piece = 0; // kludge to force illegal CSA move - for( i = 0; i < root_nmove; i++ ) { // determine the piece from the move list - int move = root_move_list[i].move; + for( i = 0; l ? all_moves[i] : i < root_nmove; i++ ) { // determine the piece from the move list + int move = (l ? all_moves[i] : root_move_list[i].move); if( I2To(move) != to ) continue; if( I2From(move) != from ) continue; if( (move & FLAG_PROMO) != flag ) continue; piece = I2PieceMove( move ); // we found the move; take the piece from it + bonanza_move = move; break; } printf("# piece corrected to %d\n", piece);fflush(stdout); @@ -141,6 +144,34 @@ printf("# piece corrected to %d\n", piece);fflush(stdout); if( promo ) piece += promote; sprintf(out, "%c%c%c%c%s", 'a'+'9'-fromX, '1'+'9'-fromY, 'a'+'9'-toX, '1'+'9'-toY, astr_table_piece[piece]); } + return bonanza_move; +} + +static void +update_exclude_list( tree_t * restrict ptree, int add, char *move_str ) +{ // [HGM] exclude: manage list of excluded moves + char dummy[20]; + int i; + if( ! exclude_list[0] ) { // nothing is excluded yet; make a copy of root move list; + for( i = 0; i < root_nmove; i++) all_moves[i] = root_move_list[i].move; + all_moves[i] = 0; + } + if ( ! strcmp(move_str, "all") ) { // all moves + if( add ) { // copy entire list of legal moves + for( i = 0; i < root_nmove; i++ ) exclude_list[i] = all_moves[i]; + } else exclude_list[0] = 0; // clear list + } else { // single move + int move = xboard_to_CSA( ptree, move_str, dummy, flag_pondering | flag_thinking); // kludge with impossible flag + for( i = 0; exclude_list[i]; i++ ) if( move == exclude_list[i] ) break; + if( add ) { // we must add the move + if( exclude_list[i] ) return; // but it was already in list + if( i >= MAX_LEGAL_MOVES - 2 ) return; // overflow + exclude_list[i] = move; exclude_list[i+1] = 0; // append move + } else { // we must delete the move + if( exclude_list[i] == 0 ) return; // but it was not there + while( (exclude_list[i] = exclude_list[i+1]) ) i++; // squeeze it out + } + } } static void @@ -173,7 +204,7 @@ Out("# command = '%s'\n", line); 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 sigint=0 done=1\n"); + "\" memory=1 smp=1 debug=1 colors=0 setboard=1 ping=1 sigint=0 exclude=1 done=1\n"); } IF("new") { forceMode = plyNr = 0; SetTimes(); return 0; } IF("easy") { strcpy(line, "ponder off"); return 0; } @@ -203,7 +234,7 @@ Out("# command = '%s'\n", line); min = 60*min + sec; myTime = hisTime = 100*min; inc = 100 * fsec; } IF("usermove") { char buf[20]; - xboard_to_CSA( ptree, line+9, buf ); + xboard_to_CSA( ptree, line+9, buf, game_status ); if(forceMode || analyze_mode) strcpy(line, "move "), line += 5; else plyNr++, SetTimes(); strcpy( line, buf ); plyNr++; @@ -212,6 +243,8 @@ Out("# command = '%s'\n", line); IF("undo") { return 0; } IF("remove") { ; } IF("ping") { Out("pong %d\n", value); } + IF("exclude") { update_exclude_list( ptree, 1, line+8 ); strcpy(line, "analyze"); return 0; } + IF("include") { update_exclude_list( ptree, 0, line+8 ); strcpy(line, "analyze"); return 0; } return 1; } #endif @@ -437,7 +470,7 @@ do_analyze( tree_t * restrict ptree ) Out("1 0 0 0 New Search\n"); // make sure lower depth is emitted, so XBoard undestand new search started #endif game_status |= flag_pondering; - iret = iterate( ptree, 0 ); + iret = iterate( ptree, flag_refer_rest ); game_status &= ~flag_pondering; return iret; } @@ -461,6 +494,7 @@ cmd_undo( tree_t * restrict ptree ) make_move_root( ptree, move_list[i], 0); } + exclude_list[0] = 0; // [HGM] exclude: exclude list cleared for new position if ( analyze_mode ) return do_analyze ( ptree ); // [HGM] analyze: analysis should continue after undo return 1; @@ -469,7 +503,7 @@ cmd_undo( tree_t * restrict ptree ) static int cmd_analyze( tree_t * restrict ptree ) -{ // [HGM] analyze: switch on analyze mode, and start analyzing +{ // [HGM] analyze: switch on analyze mode, and start analyzing (also used to force a restart) AbortDifficultCommand; analyze_mode = 1; @@ -487,6 +521,7 @@ cmd_exit( void ) if ( game_status & flag_pondering ) { game_status |= flag_quit_ponder; return 2; } analyze_mode = 0; + exclude_list[0] = 0; // [HGM] exclude: exclude list cleared after analysis return 1; } @@ -1263,6 +1298,7 @@ cmd_move( tree_t * restrict ptree, char **lasts ) | flag_rejections ) ); if ( iret < 0 ) { return iret; } + exclude_list[0] = 0; // [HGM] exclude: exclude list cleared for new position if ( analyze_mode ) return do_analyze ( ptree ); // [HGM] analyze: analysis should continue after feeding moves } @@ -1282,6 +1318,7 @@ cmd_new( tree_t * restrict ptree, char **lasts ) AbortDifficultCommand; start_pos = *lasts; move_ptr = 0; // [HGM] undo: remember start position + exclude_list[0] = 0; // [HGM] exclude: exclude list cleared for new position if ( str1 != NULL ) { diff --git a/root.c b/root.c index e778431..104c4f7 100644 --- a/root.c +++ b/root.c @@ -211,6 +211,13 @@ read_rest_list( tree_t * restrict ptree, unsigned int * restrict pmove_list ) int iret, imove; char a[65536]; + if ( analyze_mode ) { // [HGM] exclude: in analyze mode we use the interactively updated list in stead of the file + for ( imove = 0; imove < MAX_LEGAL_MOVES && exclude_list[imove]; imove++ ) + pmove_list[imove] = exclude_list[imove]; + pmove_list[imove] = 0; + return 0; + } + pf = file_open( "restraint.dat", "r" ); if ( pf == NULL ) { return -2; } diff --git a/shogi.h b/shogi.h index 1aa2585..cf00c38 100644 --- a/shogi.h +++ b/shogi.h @@ -1024,6 +1024,8 @@ extern const char ashell_h[ SHELL_H_LEN ]; extern const unsigned char aifile[ nsquare ]; extern const unsigned char airank[ nsquare ]; extern int move_list[], move_ptr; // [HGM] undo: game history (used in proce.c and makemove.c) +extern int exclude_list[]; // [HGM] exclude: 'restraint list' of moves to be excluded from analysis +extern char analyze_mode; // [HGM] exclude: used in proce.c and root.c void pv_close( tree_t * restrict ptree, int ply, int type ); void pv_copy( tree_t * restrict ptree, int ply ); -- 1.7.0.4