Increase queen attack bonus
[owl.git] / cmd.c
blobe646e93ec16ec348441ad3265e34968089aa729b
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 "move.h"
20 #include "search.h"
22 /* forward declarations of functions */
23 static void init_protover_2(void);
24 static int parse_cmd(char *cmd);
26 /* wait for a command */
27 void
28 loopcmd(void)
30 int res;
31 int move;
32 int engine_xboard;
33 char cmd[MAX_STRING];
34 char move_buf[MAX_STRING];
35 pthread_t tid;
37 while (TRUE) {
38 if (get_engine_value(&e.side) == brd.wtm &&
39 !get_engine_value(&e.force_mode)) {
40 /* start thinking in separate thread */
41 res = pthread_create(&tid, 0, process_turn, 0);
43 /* error occured */
44 if (res) {
45 fprintf(stderr, "pthread error: %s\n", strerror(res));
46 perform_cleanup();
47 exit(res);
50 pthread_mutex_lock(&e.mutex);
51 e.tid = tid;
52 e.side = NOBODY;
53 pthread_mutex_unlock(&e.mutex);
55 } else {
56 engine_xboard = get_engine_value(&e.xboard_mode);
57 if (!engine_xboard && !get_engine_value(&e.thinking))
58 fprintf(stdout, "[%s]$ ", program_name);
60 /* Ctrl+D */
61 if (!fgets(cmd, MAX_STRING, stdin)) {
62 perform_cleanup();
63 exit(0);
66 if (!strcmp(cmd, "\n"))
67 continue;
69 if (parse_cmd(cmd) || get_engine_value(&e.thinking))
70 continue;
72 /* check if we have received a move */
73 sscanf(cmd, "%s", move_buf);
75 /* parse according to the notation we are using */
76 if (get_engine_value(&e.san_notation) || !engine_xboard)
77 move = parse_move_san(move_buf);
78 else
79 move = parse_move_coord(move_buf);
81 if (!move)
82 fprintf(stdout, "Error (unknown command): %s\n", move_buf);
83 else {
84 /* OK, it is a legal move - make it */
85 make_move(move, FALSE);
86 set_engine_value(&e.side, brd.wtm);
92 static int
93 parse_cmd(char *cmd)
95 int val;
96 char *filename;
97 pthread_t tid;
98 struct epd_info_t *ei;
99 struct moves_t moves;
101 /* start thinking */
102 if (!strncmp(cmd, "go", 2)) {
103 if (!get_engine_value(&e.thinking)) {
104 set_engine_value(&e.force_mode, FALSE);
105 set_engine_value(&e.side, brd.wtm);
107 /* display current board to console */
108 } else if (!strncmp(cmd, "board", 5))
109 print_board();
111 /* xboard send this command */
112 else if (!strncmp(cmd, "xboard", 6))
113 set_engine_value(&e.xboard_mode, TRUE);
114 /* stop thinking */
115 else if (!strncmp(cmd, "force", 5)) {
116 set_engine_value(&e.force_mode, TRUE);
117 set_engine_value(&e.side, NOBODY);
118 set_engine_value((int *)&e.stop_time, 0);
119 set_engine_value((int *)&e.max_stop_time, 0);
120 if (e.tid) {
121 val = pthread_join(e.tid, 0);
122 if (val)
123 fprintf(stderr, "Error occured: %s\n", strerror(val));
124 e.tid = 0;
126 /* move now command */
127 } else if (!strncmp(cmd, "?", 1)) {
128 set_engine_value((int *)&e.stop_time, 0);
129 set_engine_value((int *)&e.max_stop_time, 0);
130 /* the opponent is a computer */
131 } else if (!strncmp(cmd, "computer", 8))
132 set_engine_value(&e.play_computer, TRUE);
134 /* xboard support version protocol version 2. we should reply
135 by 'feature' command */
136 else if (!strncmp(cmd, "protover 2", 10)) {
137 set_engine_value(&e.san_notation, TRUE);
138 init_protover_2();
140 /* start new game */
141 } else if (!strncmp(cmd, "new", 3)) {
142 new_game();
143 set_engine_value(&e.play_computer, FALSE);
144 set_engine_value(&e.force_mode, FALSE);
145 set_engine_value(&e.max_depth, MAX_PLY);
146 set_engine_value(&e.side, BLACK);
147 /* display thinking */
148 } else if (!strncmp(cmd, "post", 4))
149 set_engine_value(&e.post_mode, TRUE);
151 /* do not display thinking */
152 else if (!strncmp(cmd, "nopost", 6))
153 set_engine_value(&e.post_mode, FALSE);
155 /* time remaining for the engine */
156 else if (sscanf(cmd, "time %d", &val) == 1) {
157 set_engine_value(&e.max_time, val / \
158 get_engine_value(&e.time_div));
159 set_engine_value(&e.max_depth, MAX_PLY);
160 set_engine_value(&e.fixed_time, FALSE);
162 } else if (sscanf(cmd, "otim %d", &val) == 1) {
163 /* handle but skip this */
164 } else if (sscanf(cmd, "st %d", &val) == 1) {
165 set_engine_value(&e.max_time, val);
166 set_engine_value(&e.max_depth, MAX_PLY);
167 set_engine_value(&e.fixed_time, TRUE);
169 /* set search depth */
170 } else if (sscanf(cmd, "sd %d", &val) == 1) {
171 set_engine_value(&e.max_time, 100000);
172 set_engine_value(&e.max_depth, val);
174 /* we can't change some parameters while searching */
175 /* enable/disable NULL move pruning (CLI command) */
176 } else if (!get_engine_value(&e.thinking) && !strncmp(cmd, "null on", 7))
177 e.null_pruning = TRUE;
178 else if (!get_engine_value(&e.thinking) && !strncmp(cmd, "null off", 8))
179 e.null_pruning = FALSE;
181 /* enable/disable Late Move Reductions (CLI command) */
182 else if (!get_engine_value(&e.thinking) && !strncmp(cmd, "lmr on", 6))
183 e.lmr = TRUE;
184 else if (!get_engine_value(&e.thinking) && !strncmp(cmd, "lmr off", 7))
185 e.lmr = FALSE;
187 /* enable/disable Delta Pruning (CLI command) */
188 else if (!get_engine_value(&e.thinking) && !strncmp(cmd, "delta on", 8))
189 e.delta_pruning = TRUE;
190 else if (!get_engine_value(&e.thinking) && !strncmp(cmd, "delta off", 9))
191 e.delta_pruning = FALSE;
193 /* enable/disable Futility Pruning (CLI command) */
194 else if (!get_engine_value(&e.thinking) && !strncmp(cmd, "futil on", 8))
195 e.futility_pruning = TRUE;
196 else if (!get_engine_value(&e.thinking) && !strncmp(cmd, "futil off", 9))
197 e.futility_pruning = FALSE;
199 else if (!strncmp(cmd, "epd", 3)) {
200 if (!get_engine_value(&e.thinking)) {
201 /* EPD - solve test positions */
202 ei = malloc(sizeof(struct epd_info_t));
203 filename = malloc(MAX_STRING);
205 sscanf(cmd, "epd %s %d %d %d", filename, &ei->think_time, \
206 &ei->max_tests, &ei->first_test);
208 ei->filename = filename;
209 pthread_create(&tid, 0, run_epd_test, ei);
211 /* setup board from FEN position */
212 } else if (!strncmp(cmd, "setboard", 8)) {
213 if (!setup_board(cmd + 9))
214 fprintf(stdout, "Invalid FEN position: %s\n", cmd + 9);
215 set_engine_value(&e.side, NOBODY);
217 /* print FEN to stdout */
218 } else if (!strncmp(cmd, "fen", 3))
219 fprintf(stdout, "%s\n", current_fen_position(cmd));
221 /* takeback last move */
222 else if (!strncmp(cmd, "undo", 4)) {
223 set_engine_value(&e.side, NOBODY);
224 if (game_history.count)
225 takeback();
227 /* exit engine */
228 } else if (!strncmp(cmd, "quit", 4)) {
229 perform_cleanup();
230 exit(0);
232 /* reply with 'pong' command */
233 } else if (sscanf(cmd, "ping %d", &val) == 1)
234 fprintf(stdout, "pong %d\n", val);
236 /* print possible moves to stdout */
237 else if (!strncmp(cmd, "moves", 5)) {
238 gen_legal_moves(&moves);
239 print_moves_san(&moves);
240 } else
241 /* invalid command, maybe it is a move */
242 return FALSE;
244 return TRUE;
247 /* default xboard parameters */
248 static void
249 init_protover_2(void)
251 /* disable Unix signals SIGINT and SIGTERM and tell some of our
252 parameters */
253 fprintf(stdout, "feature myname \"%s\"\n" \
254 "feature san=1\n" \
255 "feature colors=0\n" \
256 "feature setboard=1\n" \
257 "feature sigint=0\n" \
258 "feature sigterm=0\n" \
259 "feature ping=1\n" \
260 "feature done=1\n", program_name);