Implement undo command
[bonanza.git] / proce.c
diff --git a/proce.c b/proce.c
index 94db5d0..214c78b 100644 (file)
--- 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<last; i++) {
+    make_move_root( ptree, move_list[i], 0);
+  }
+  return 1;
+}
+
+
+static int
 is_move( const char *str )
 {
   if ( isdigit( (int)str[0] ) && isdigit( (int)str[1] )
@@ -1159,8 +1186,11 @@ 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 );