From: H.G. Muller Date: Fri, 13 Sep 2013 13:42:27 +0000 (+0200) Subject: Implement undo command X-Git-Url: http://winboard.nl/cgi-bin?p=bonanza.git;a=commitdiff_plain;h=b850f7cbcdc13f78355a7dc302e3e27a0552bb37 Implement undo command This is decoded with the native bonanza commands, and should thus work both in xboard and native mode. It resets the game by faking a 'new' command, and then loads all moves except the last. For this the move list and startup string needed to be remembered. --- diff --git a/makemove.c b/makemove.c index 83d8c9e..7ed2b7d 100644 --- a/makemove.c +++ b/makemove.c @@ -421,6 +421,7 @@ make_move_root( tree_t * restrict ptree, unsigned int move, int flag ) } root_turn = Flip( root_turn ); + move_list[move_ptr++] = move; // [HGM] undo: remember all moves played in root /* detect checkmate */ if ( check && is_mate( ptree, 1 ) ) { game_status |= flag_mated; } @@ -500,6 +501,7 @@ unmake_move_root( tree_t * restrict ptree, unsigned int move ) root_nrep -= 1; game_status &= ~( flag_drawn | flag_mated ); root_turn = Flip(root_turn); + move_ptr--; // [HGM] undo: clip last move off game history ptree->save_material[1] = ptree->save_material[0]; UnMakeMove( root_turn, move, 1 ); diff --git a/proce.c b/proce.c index 94db5d0..214c78b 100644 --- a/proce.c +++ b/proce.c @@ -74,6 +74,7 @@ static int cmd_new( tree_t * restrict ptree, char **lasts ); static int cmd_read( tree_t * restrict ptree, char **lasts ); static int cmd_resign( tree_t * restrict ptree, char **lasts ); static int cmd_time( char **lasts ); +static int cmd_undo( tree_t * restrict ptree ); // [HGM] undo static int is_move( const char *str ); @@ -90,6 +91,9 @@ procedure( tree_t * restrict ptree ) return proce_cui( ptree ); } +char *start_pos, start_data[512]; // [HGM] undo: for remembering start position +int move_list[1024], move_ptr; + #ifdef XBOARD #define IF(X) else if(!strcmp(command, X)) @@ -168,7 +172,8 @@ Out("# from=%d\n",from); sprintf(line, "%c%c%c%c%s", 'a'+'9'-fromX, '1'+'9'-fromY, 'a'+'9'-toX, '1'+'9'-toY, astr_table_piece[abs(BOARD[from]) + (promo == '+' ? promote : 0)]); } - plyNr++; return 0; + plyNr++; + return 0; } IF("undo") { ; } IF("remove") { ; } @@ -214,6 +219,7 @@ proce_cui( tree_t * restrict ptree ) if ( ! strcmp( token, "resign" ) ) { return cmd_resign( ptree, &last ); } if ( ! strcmp( token, "suspend" ) ) { return cmd_suspend(); } if ( ! strcmp( token, "time" ) ) { return cmd_time( &last ); } + if ( ! strcmp( token, "undo" ) ) { return cmd_undo( ptree ); } // [HGM] undo #if defined(CSA_LAN) if ( ! strcmp( token, "connect" ) ) { return cmd_connect( ptree, &last ); } #endif @@ -385,6 +391,27 @@ cmd_mnjmove( tree_t * restrict ptree, char **lasts, int is_alter ) static int +cmd_undo( tree_t * restrict ptree ) +{ // [HGM] undo: restart the game, and feed all moves except the last + int i, last = move_ptr; + char *p = start_data; + if( move_ptr <= 0 ) { + str_error = "undo past start of game ignored"; + return -2; + } + + AbortDifficultCommand; + + last--; + cmd_new( ptree, &p ); + for(i=0; i