1 #include <signal.h>
2 #include "chess.h"
3 #include "data.h"
4 /* last modified 01/17/09 */
5 /*
6 *******************************************************************************
7 * *
8 * Interrupt() is used to read in a move when the operator types something *
9 * while a search is in progress (during pondering as one example.) This *
10 * routine reads in a command (move) and then makes two attempts to use this *
11 * input: (1) call Option() to see if the command can be executed; (2) try *
12 * InputMove() to see if this input is a legal move; If so, and we are *
13 * pondering see if it matches the move we are pondering. *
14 * *
15 *******************************************************************************
16 */
Interrupt(int ply)17 void Interrupt(int ply) {
18 TREE *const tree = block[0];
19 int temp, i, left = 0, readstat, result, time_used, save_move_number;
20
21 /*
22 ************************************************************
23 * *
24 * If trying to find a move to ponder, and the operator *
25 * types a command, exit a.s.a.p. *
26 * *
27 ************************************************************
28 */
29 if (puzzling)
30 abort_search = 2;
31 /*
32 ************************************************************
33 * *
34 * First check to see if this is a command by calling *
35 * Option(). Option() will return a 0 if it didn't *
36 * recognize the command; otherwise it returns a 1 if the *
37 * command was executed, or a 2 if we need to abort the *
38 * search to execute the command. *
39 * *
40 ************************************************************
41 */
42 else
43 while (FOREVER) {
44 readstat = Read(0, buffer);
45 if (readstat <= 0)
46 break;
47 nargs = ReadParse(buffer, args, " \t;");
48 if (nargs == 0) {
49 Print(32, "ok.\n");
50 break;
51 }
52 if (strcmp(args[0], ".")) {
53 save_move_number = move_number;
54 if (!game_wtm)
55 move_number--;
56 if (root_wtm)
57 Print(32, "Black(%d): %s\n", move_number, buffer);
58 else
59 Print(32, "White(%d): %s\n", move_number, buffer);
60 move_number = save_move_number;
61 }
62 /*
63 ************************************************************
64 * *
65 * "." command displays status of current search (this is *
66 * part of winboard protocol.) *
67 * *
68 ************************************************************
69 */
70 if (!strcmp(args[0], ".")) {
71 if (xboard) {
72 end_time = ReadClock();
73 time_used = (end_time - start_time);
74 printf("stat01: %d ", time_used);
75 printf("%" PRIu64 " ", tree->nodes_searched);
76 printf("%d ", iteration);
77 for (i = 0; i < n_root_moves; i++)
78 if (!(root_moves[i].status & 8))
79 left++;
80 printf("%d %d\n", left, n_root_moves);
81 fflush(stdout);
82 break;
83 } else {
84 end_time = ReadClock();
85 time_used = (end_time - start_time);
86 printf("time:%s ", DisplayTime(time_used));
87 printf("nodes:%" PRIu64 "\n", tree->nodes_searched);
88 #if (CPUS > 1)
89 ThreadTrace(block[0], 0, 1);
90 #endif
91 }
92 }
93 /*
94 ************************************************************
95 * *
96 * "?" command says "move now!" *
97 * *
98 ************************************************************
99 */
100 else if (!strcmp(args[0], "?")) {
101 if (thinking) {
102 abort_search = 1;
103 }
104 }
105 /*
106 ************************************************************
107 * *
108 * "@" command says "assume ponder move was played." *
109 * *
110 ************************************************************
111 */
112 else if (!strcmp(args[0], "@")) {
113 if (pondering) {
114 predicted++;
115 input_status = 1;
116 pondering = 0;
117 thinking = 1;
118 opponent_end_time = ReadClock();
119 program_start_time = ReadClock();
120 Print(32, "predicted move made.\n");
121 }
122 }
123 /*
124 ************************************************************
125 * *
126 * Next see if Option() recognizes this as a command. Note *
127 * some commands can't be executed in the middle of a *
128 * search. Option() returns a value >= 2 in such cases. *
129 * If we are pondering, we can back out of the search and *
130 * execute the command, otherwise we produce an error and *
131 * continue searching for our move. *
132 * *
133 ************************************************************
134 */
135 else {
136 save_move_number = move_number;
137 if (!analyze_mode && !game_wtm)
138 move_number--;
139 result = Option(tree);
140 move_number = save_move_number;
141 if (result >= 2) {
142 if (thinking && result != 3)
143 Print(32, "command not legal now.\n");
144 else {
145 abort_search = 2;
146 input_status = 2;
147 break;
148 }
149 } else if ((result != 1) && analyze_mode) {
150 abort_search = 1;
151 input_status = 2;
152 break;
153 }
154 /*
155 ************************************************************
156 * *
157 * Option() didn't recognize the input as a command so now *
158 * we check to see if the operator typed a move. If so, *
159 * and it matched the predicted move, switch from *
160 * pondering to thinking to start the timer. If this is a *
161 * move, but not the predicted move, abort the search and *
162 * start over with the right move. *
163 * *
164 ************************************************************
165 */
166 else if (!result) {
167 if (pondering) {
168 nargs = ReadParse(buffer, args, " \t;");
169 temp = InputMove(tree, 0, Flip(root_wtm), 1, 1, args[0]);
170 if (temp) {
171 if ((From(temp) == From(ponder_move))
172 && (To(temp) == To(ponder_move))
173 && (Piece(temp) == Piece(ponder_move))
174 && (Captured(temp) == Captured(ponder_move))
175 && (Promote(temp) == Promote(ponder_move))) {
176 predicted++;
177 input_status = 1;
178 pondering = 0;
179 thinking = 1;
180 opponent_end_time = ReadClock();
181 program_start_time = ReadClock();
182 Print(32, "predicted move made.\n");
183 } else {
184 input_status = 2;
185 abort_search = 2;
186 break;
187 }
188 } else if (!strcmp(args[0], "go") || !strcmp(args[0], "move")
189 || !strcmp(args[0], "SP")) {
190 abort_search = 2;
191 break;
192 } else
193 Print(4095, "Illegal move: %s\n", args[0]);
194 } else
195 Print(4095, "unrecognized/illegal command: %s\n", args[0]);
196 }
197 }
198 }
199 if (log_file)
200 fflush(log_file);
201 }
202