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