From 3f0517778128278a9e50ebde3ac8b237da1b62ef 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 | 57 +++++++++++++++++++++++++++++++++++++++++++++++---------- root.c | 6 +++--- shogi.h | 1 + 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/proce.c b/proce.c index 1b57b94..a08b5d9 100644 --- a/proce.c +++ b/proce.c @@ -129,6 +129,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 all_moves[MAX_LEGAL_MOVES]; #ifdef XBOARD #define IF(X) else if(!strcmp(command, X)) @@ -136,11 +137,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 @@ -152,21 +153,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); @@ -174,6 +177,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( moves_ignore[0] == MOVE_NA ) { // 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++ ) moves_ignore[i] = all_moves[i]; + } else moves_ignore[0] = MOVE_NA; // 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; moves_ignore[i] != MOVE_NA; i++ ) if( move == moves_ignore[i] ) break; + if( add ) { // we must add the move + if( moves_ignore[i] != MOVE_NA ) return; // but it was already in list + if( i >= MAX_LEGAL_MOVES - 2 ) return; // overflow + moves_ignore[i] = move; moves_ignore[i+1] = MOVE_NA; // append move + } else { // we must delete the move + if( moves_ignore[i] == MOVE_NA ) return; // but it was not there + while( (moves_ignore[i] = moves_ignore[i+1]) ) i++; // squeeze it out + } + } } static void @@ -206,7 +237,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; } @@ -236,7 +267,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++; @@ -245,6 +276,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 @@ -574,6 +607,7 @@ cmd_undo( tree_t * restrict ptree ) make_move_root( ptree, move_list[i], 0); } + moves_ignore[0] = MOVE_NA; // [HGM] exclude: exclude list cleared for new position if ( analyze_mode ) return do_analyze ( ptree ); // [HGM] analyze: analysis should continue after undo return 1; @@ -582,7 +616,7 @@ cmd_undo( tree_t * restrict ptree ) static int CONV 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; @@ -600,6 +634,7 @@ cmd_exit( void ) if ( game_status & flag_pondering ) { game_status |= flag_quit_ponder; return 2; } analyze_mode = 0; + moves_ignore[0] = MOVE_NA; // [HGM] exclude: exclude list cleared after analysis return 1; } @@ -1542,6 +1577,7 @@ static int CONV cmd_move( tree_t * restrict ptree, char **lasts ) } while ( str != NULL ); + moves_ignore[0] = MOVE_NA; // [HGM] exclude: exclude list cleared for new position if ( analyze_mode ) return do_analyze ( ptree ); // [HGM] analyze: analysis should continue after feeding moves return 1; @@ -1559,6 +1595,7 @@ static int CONV cmd_new( tree_t * restrict ptree, char **lasts ) AbortDifficultCommand; start_pos = *lasts; move_ptr = 0; // [HGM] undo: remember start position + moves_ignore[0] = MOVE_NA; // [HGM] exclude: exclude list cleared for new position if ( str1 != NULL ) { diff --git a/root.c b/root.c index d83b417..b3faa2d 100644 --- a/root.c +++ b/root.c @@ -2,7 +2,7 @@ #include #include "shogi.h" -#if defined(USI) || defined(MNJ_LAN) +#if defined(USI) || defined(MNJ_LAN) || defined(XBOARD) static int is_move_ignore( unsigned int move ); #endif @@ -30,7 +30,7 @@ make_root_move_list( tree_t * restrict ptree ) MakeMove( root_turn, move, 1 ); if ( ! InCheck( root_turn ) -#if defined(USI) || defined(MNJ_LAN) +#if defined(USI) || defined(MNJ_LAN) || defined(XBOARD) && ! is_move_ignore( move ) #endif ) @@ -157,7 +157,7 @@ make_root_move_list( tree_t * restrict ptree ) } -#if defined(USI) || defined(MNJ_LAN) +#if defined(USI) || defined(MNJ_LAN) || defined(XBOARD) static int CONV is_move_ignore( unsigned int move ) { diff --git a/shogi.h b/shogi.h index 62800dd..395126f 100644 --- a/shogi.h +++ b/shogi.h @@ -957,6 +957,7 @@ extern const char ach_turn[2]; 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 char analyze_mode; // [HGM] exclude: used in proce.c and root.c #if defined(DFPN_CLIENT) # define DFPN_CLIENT_SIZE_SIGNATURE 64 -- 1.7.0.4