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