+ Files owl_SOURCES - add headers
[owl.git] / cmd.c
blobbabdbadf15be0a5a853899e6df69c5ac6e462615
1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 #include "common.h"
17 #include "board.h"
18 #include "engine.h"
19 #include "evaluate.h"
20 #include "move.h"
21 #include "search.h"
23 /* forward declarations of functions */
24 static void init_protover_2(void);
25 static int parse_cmd(char *cmd);
27 /* wait for a command */
28 void
29 loopcmd(void)
31 int res;
32 int move;
33 int engine_xboard;
34 char cmd[MAX_STRING];
35 char move_buf[MAX_STRING];
36 pthread_t tid;
38 while (TRUE) {
39 if (get_engine_value(&e.side) == brd.wtm &&
40 !get_engine_value(&e.force_mode)) {
41 /* start thinking in separate thread */
42 res = pthread_create(&tid, 0, process_turn, 0);
44 /* error occured */
45 if (res) {
46 fprintf(stderr, "pthread error: %s\n", strerror(res));
47 perform_cleanup();
48 exit(res);
51 pthread_mutex_lock(&e.mutex);
52 e.tid = tid;
53 e.side = NOBODY;
54 pthread_mutex_unlock(&e.mutex);
56 } else {
57 engine_xboard = get_engine_value(&e.xboard_mode);
58 if (!engine_xboard && !get_engine_value(&e.thinking))
59 fprintf(stdout, "[%s]$ ", program_name);
61 /* Ctrl+D */
62 if (!fgets(cmd, MAX_STRING, stdin)) {
63 perform_cleanup();
64 exit(0);
67 if (!strcmp(cmd, "\n"))
68 continue;
70 if (parse_cmd(cmd) || get_engine_value(&e.thinking))
71 continue;
73 /* check if we have received a move */
74 sscanf(cmd, "%s", move_buf);
76 /* parse according to the notation we are using */
77 if (get_engine_value(&e.san_notation) || !engine_xboard)
78 move = parse_move_san(move_buf);
79 else
80 move = parse_move_coord(move_buf);
82 if (!move)
83 fprintf(stdout, "Error (unknown command): %s\n", move_buf);
84 else {
85 /* OK, it is a legal move - make it */
86 make_move(move, FALSE);
87 set_engine_value(&e.side, brd.wtm);
93 static int
94 parse_cmd(char *cmd)
96 int val;
97 int inc;
98 char total_time[MAX_STRING];
99 char *filename;
100 pthread_t tid;
101 struct epd_info_t *ei;
102 struct moves_t moves;
104 /* start thinking */
105 if (!strncmp(cmd, "go", 2)) {
106 if (!get_engine_value(&e.thinking)) {
107 set_engine_value(&e.force_mode, FALSE);
108 set_engine_value(&e.side, brd.wtm);
110 /* display current board to console */
111 } else if (!strncmp(cmd, "board", 5))
112 print_board();
114 /* xboard send this command */
115 else if (!strncmp(cmd, "xboard", 6))
116 set_engine_value(&e.xboard_mode, TRUE);
117 /* stop thinking */
118 else if (!strncmp(cmd, "force", 5)) {
119 set_engine_value(&e.force_mode, TRUE);
120 set_engine_value(&e.side, NOBODY);
121 set_engine_value((int *)&e.stop_time, 0);
122 set_engine_value((int *)&e.max_stop_time, 0);
123 if (e.tid) {
124 val = pthread_join(e.tid, 0);
125 if (val)
126 fprintf(stderr, "Error occured: %s\n", strerror(val));
127 e.tid = 0;
129 /* move now command */
130 } else if (!strncmp(cmd, "?", 1)) {
131 set_engine_value((int *)&e.stop_time, 0);
132 set_engine_value((int *)&e.max_stop_time, 0);
133 /* the opponent is a computer */
134 } else if (!strncmp(cmd, "computer", 8))
135 set_engine_value(&e.play_computer, TRUE);
137 /* xboard support version protocol version 2. we should reply
138 by 'feature' command */
139 else if (!strncmp(cmd, "protover 2", 10)) {
140 set_engine_value(&e.san_notation, TRUE);
141 init_protover_2();
143 /* start new game */
144 } else if (!strncmp(cmd, "new", 3)) {
145 new_game();
146 set_engine_value(&e.play_computer, FALSE);
147 set_engine_value(&e.force_mode, FALSE);
148 set_engine_value(&e.max_depth, MAX_PLY);
149 set_engine_value(&e.side, BLACK);
150 /* display thinking */
151 } else if (!strncmp(cmd, "post", 4))
152 set_engine_value(&e.post_mode, TRUE);
154 /* do not display thinking */
155 else if (!strncmp(cmd, "nopost", 6))
156 set_engine_value(&e.post_mode, FALSE);
158 /* time remaining for the engine */
159 else if (sscanf(cmd, "time %d", &val) == 1) {
160 set_engine_value(&e.max_time, val / \
161 get_engine_value(&e.time_div));
162 set_engine_value(&e.max_depth, MAX_PLY);
163 set_engine_value(&e.fixed_time, FALSE);
165 } else if (sscanf(cmd, "otim %d", &val) == 1) {
166 /* handle but skip this */
167 } else if (sscanf(cmd, "st %d", &val) == 1) {
168 set_engine_value(&e.max_time, val);
169 set_engine_value(&e.max_depth, MAX_PLY);
170 set_engine_value(&e.fixed_time, TRUE);
172 /* set search depth */
173 } else if (sscanf(cmd, "sd %d", &val) == 1) {
174 set_engine_value(&e.max_time, 100000);
175 set_engine_value(&e.max_depth, val);
176 } else if (sscanf(cmd, "level %d %s %d", &val, &total_time, &inc) == 3) {
177 set_engine_value(&e.inc_time, inc * 100);
178 /* we can't change some parameters while searching */
179 /* enable/disable NULL move pruning (CLI command) */
180 } else if (!get_engine_value(&e.thinking) && !strncmp(cmd, "null on", 7))
181 e.null_pruning = TRUE;
182 else if (!get_engine_value(&e.thinking) && !strncmp(cmd, "null off", 8))
183 e.null_pruning = FALSE;
185 /* enable/disable Late Move Reductions (CLI command) */
186 else if (!get_engine_value(&e.thinking) && !strncmp(cmd, "lmr on", 6))
187 e.lmr = TRUE;
188 else if (!get_engine_value(&e.thinking) && !strncmp(cmd, "lmr off", 7))
189 e.lmr = FALSE;
191 /* enable/disable Delta Pruning (CLI command) */
192 else if (!get_engine_value(&e.thinking) && !strncmp(cmd, "delta on", 8))
193 e.delta_pruning = TRUE;
194 else if (!get_engine_value(&e.thinking) && !strncmp(cmd, "delta off", 9))
195 e.delta_pruning = FALSE;
197 /* enable/disable Futility Pruning (CLI command) */
198 else if (!get_engine_value(&e.thinking) && !strncmp(cmd, "futil on", 8))
199 e.futility_pruning = TRUE;
200 else if (!get_engine_value(&e.thinking) && !strncmp(cmd, "futil off", 9))
201 e.futility_pruning = FALSE;
203 else if (!strncmp(cmd, "epd", 3)) {
204 if (!get_engine_value(&e.thinking)) {
205 /* EPD - solve test positions */
206 ei = malloc(sizeof(struct epd_info_t));
207 filename = malloc(MAX_STRING);
209 sscanf(cmd, "epd %s %d %d %d", filename, &ei->think_time, \
210 &ei->max_tests, &ei->first_test);
212 ei->filename = filename;
213 pthread_create(&tid, 0, run_epd_test, ei);
215 /* setup board from FEN position */
216 } else if (!strncmp(cmd, "setboard", 8)) {
217 if (!setup_board(cmd + 9))
218 fprintf(stdout, "Invalid FEN position: %s\n", cmd + 9);
219 set_engine_value(&e.side, NOBODY);
221 /* print FEN to stdout */
222 } else if (!strncmp(cmd, "fen", 3))
223 fprintf(stdout, "%s\n", current_fen_position(cmd));
225 /* takeback last move */
226 else if (!strncmp(cmd, "undo", 4)) {
227 set_engine_value(&e.side, NOBODY);
228 if (game_history.count)
229 takeback();
231 /* exit engine */
232 } else if (!strncmp(cmd, "quit", 4)) {
233 perform_cleanup();
234 exit(0);
236 /* reply with 'pong' command */
237 } else if (sscanf(cmd, "ping %d", &val) == 1)
238 fprintf(stdout, "pong %d\n", val);
240 /* print possible moves to stdout */
241 else if (!strncmp(cmd, "moves", 5)) {
242 gen_legal_moves(&moves);
243 print_moves_san(&moves);
244 } else if (!strncmp(cmd, "eval", 4))
245 printf("eval = %d\n", evaluate(-MATE_VALUE, MATE_VALUE));
246 else
247 /* invalid command, maybe it is a move */
248 return FALSE;
250 return TRUE;
253 /* default xboard parameters */
254 static void
255 init_protover_2(void)
257 /* disable Unix signals SIGINT and SIGTERM and tell some of our
258 parameters */
259 fprintf(stdout, "feature myname \"%s\"\n" \
260 "feature san=1\n" \
261 "feature colors=0\n" \
262 "feature setboard=1\n" \
263 "feature sigint=0\n" \
264 "feature sigterm=0\n" \
265 "feature ping=1\n" \
266 "feature done=1\n", program_name);