Implement undo command
[bonanza.git] / proce.c
diff --git a/proce.c b/proce.c
index 6538fb9..3de4d5e 100644 (file)
--- a/proce.c
+++ b/proce.c
@@ -90,6 +90,7 @@ static int CONV cmd_move( tree_t * restrict ptree, char **lasts );
 static int CONV cmd_new( tree_t * restrict ptree, char **lasts );
 static int CONV cmd_read( tree_t * restrict ptree, char **lasts );
 static int CONV cmd_resign( tree_t * restrict ptree, char **lasts );
+static int CONV cmd_undo( tree_t * restrict ptree );    // [HGM] undo
 static int CONV cmd_time( char **lasts );
 
 
@@ -122,6 +123,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))
 
@@ -200,7 +204,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")   { ; }
@@ -227,6 +232,7 @@ static int CONV proce_cui( tree_t * restrict ptree )
     if ( ! strcmp( token, "xboard" ) )  { xboard_mode = 1; game_status |= flag_noprompt; return 1; }
   }
 #endif
+  if ( ! strcmp( token, "undo" ) )      { return cmd_undo( ptree ); }    // [HGM] undo
   if ( is_move( token ) ) { return cmd_usrmove( ptree, token, &last ); }
   if ( ! strcmp( token, "s" ) )         { return cmd_move_now(); }
   if ( ! strcmp( token, "beep" ) )      { return cmd_beep( &last); }
@@ -496,6 +502,27 @@ cmd_mnjmove( tree_t * restrict ptree, char **lasts, int num_alter )
 #endif
 
 
+static int CONV
+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<last; i++) {
+    make_move_root( ptree, move_list[i], 0);
+  }
+  return 1;
+}
+
+
 #if defined(USI)
 static int CONV proce_usi( tree_t * restrict ptree )
 {
@@ -1435,8 +1462,11 @@ static int CONV cmd_new( tree_t * restrict ptree, char **lasts )
 
   AbortDifficultCommand;
 
+  start_pos = *lasts; move_ptr = 0; // [HGM] undo: remember start position
+
   if ( str1 != NULL )
     {
+      strncpy(start_data, str1, 511); // [HGM] undo: remember start position
       memset( &min_posi.asquare, empty, nsquare );
       min_posi.hand_black = min_posi.hand_white = 0;
       iret = read_board_rep1( str1, &min_posi );