1 #include "chess.h"
2 #include "data.h"
3 /* last modified 01/18/09 */
4 /*
5  *******************************************************************************
6  *                                                                             *
7  *   Analyze() is used to handle the "analyze" command.  This mode basically   *
8  *   puts Crafty into a "permanent pondering" state, where it reads a move     *
9  *   from the input stream, and then "ponders" for the opposite side.          *
10  *   Whenever a move is entered, Crafty reads this move, updates the game      *
11  *   board, and then starts "pondering" for the other side.                    *
12  *                                                                             *
13  *   The purpose of this mode is to force Crafty to follow along in a game,    *
14  *   providing analysis continually for the side on move until a move is       *
15  *   entered, advancing the game to the next position.                         *
16  *                                                                             *
17  *******************************************************************************
18  */
Analyze()19 void Analyze() {
20   int i, v, move, back_number, readstat = 1;
21   TREE *const tree = block[0];
22 
23 /*
24  ************************************************************
25  *                                                          *
26  *  Initialize.                                             *
27  *                                                          *
28  ************************************************************
29  */
30   int save_swindle_mode = swindle_mode;
31 
32   swindle_mode = 0;
33   ponder_move = 0;
34   analyze_mode = 1;
35   if (!xboard)
36     display_options |= 1 + 2 + 4;
37   printf("Analyze Mode: type \"exit\" to terminate.\n");
38 /*
39  ************************************************************
40  *                                                          *
41  *  Now loop waiting on input, searching the current        *
42  *  position continually until a move comes in.             *
43  *                                                          *
44  ************************************************************
45  */
46   while (FOREVER) {
47     do {
48       last_pv.pathd = 0;
49       last_pv.pathl = 0;
50       input_status = 0;
51       pondering = 1;
52       tree->status[1] = tree->status[0];
53       Iterate(game_wtm, think, 0);
54       pondering = 0;
55       if (book_move)
56         moves_out_of_book = 0;
57       if (!xboard) {
58         if (game_wtm)
59           printf("analyze.White(%d): ", move_number);
60         else
61           printf("analyze.Black(%d): ", move_number);
62         fflush(stdout);
63       }
64 /*
65  ************************************************************
66  *                                                          *
67  *  If we get back to here, something has been typed in and *
68  *  is in the command buffer normally, unless the search    *
69  *  terminated naturally due to finding a mate or reaching  *
70  *  the max depth allowable.                                *
71  *                                                          *
72  ************************************************************
73  */
74       if (!input_status)
75         do {
76           readstat = Read(1, buffer);
77           if (readstat < 0)
78             break;
79           nargs = ReadParse(buffer, args, " \t;");
80           Print(32, "%s\n", buffer);
81           if (strstr(args[0], "timeleft") && !xboard) {
82             if (game_wtm)
83               printf("analyze.White(%d): ", move_number);
84             else
85               printf("analyze.Black(%d): ", move_number);
86             fflush(stdout);
87           }
88         } while (strstr(args[0], "timeleft"));
89       else
90         nargs = ReadParse(buffer, args, " \t;");
91       if (readstat < 0)
92         break;
93       move = 0;
94       if (!strcmp(args[0], "exit"))
95         break;
96 /*
97  ************************************************************
98  *                                                          *
99  *  First, check for the special analyze command "back n"   *
100  *  and handle it if present, otherwise try Option() to see *
101  *  if it recognizes the input as a command.                *
102  *                                                          *
103  ************************************************************
104  */
105       if (OptionMatch("back", args[0])) {
106         if (nargs > 1)
107           back_number = atoi(args[1]);
108         else
109           back_number = 1;
110         for (i = 0; i < back_number; i++) {
111           game_wtm = Flip(game_wtm);
112           if (Flip(game_wtm))
113             move_number--;
114         }
115         if (move_number == 0) {
116           move_number = 1;
117           game_wtm = 1;
118         }
119         sprintf(buffer, "reset %d", move_number);
120         Option(tree);
121         display = tree->position;
122       } else if (Option(tree)) {
123         display = tree->position;
124       }
125 /*
126  ************************************************************
127  *                                                          *
128  *  If InputMove() can recognize this as a move, make it,   *
129  *  swap sides, and return to the top of the loop to call   *
130  *  search from this new position.                          *
131  *                                                          *
132  ************************************************************
133  */
134       else if ((move = InputMove(tree, 0, game_wtm, 1, 0, buffer))) {
135         char *outmove = OutputMove(tree, 0, game_wtm, move);
136 
137         if (history_file) {
138           fseek(history_file, ((move_number - 1) * 2 + 1 - game_wtm) * 10,
139               SEEK_SET);
140           fprintf(history_file, "%9s\n", outmove);
141         }
142         if (game_wtm)
143           Print(32, "White(%d): ", move_number);
144         else
145           Print(32, "Black(%d): ", move_number);
146         Print(32, "%s\n", outmove);
147         if (speech) {
148           char announce[64];
149 
150           strcpy(announce, "./speak ");
151           strcat(announce, outmove);
152           strcat(announce, " &");
153           v = system(announce);
154           if (v != 0)
155             perror("Analyze() system() error: ");
156         }
157         MakeMoveRoot(tree, game_wtm, move);
158         display = tree->position;
159         last_mate_score = 0;
160         if (log_file)
161           DisplayChessBoard(log_file, tree->position);
162       }
163 /*
164  ************************************************************
165  *                                                          *
166  *  If Option() didn't handle the input, then it is illegal *
167  *  and should be reported to the user.                     *
168  *                                                          *
169  ************************************************************
170  */
171       else {
172         pondering = 0;
173         if (Option(tree) == 0)
174           printf("illegal move: %s\n", buffer);
175         pondering = 1;
176         display = tree->position;
177       }
178     } while (!move);
179     if (readstat < 0 || !strcmp(args[0], "exit"))
180       break;
181     game_wtm = Flip(game_wtm);
182     if (game_wtm)
183       move_number++;
184   }
185   analyze_mode = 0;
186   printf("analyze complete.\n");
187   pondering = 0;
188   swindle_mode = save_swindle_mode;
189 }
190