1 /***************************************************************************
2 engine.cpp - description
4 begin : mer ott 23 2002
5 copyright : (C) 2002-2005 by Maurizio Monge
6 email : monge@linuz.sns.it
7 ***************************************************************************/
9 /***************************************************************************
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 ***************************************************************************/
21 #include "search_gui.h"
24 Engine
* Engine::instance
= NULL
;
35 mv_done
= new Move
[4096];
38 save_buf
= new SaveBuf
[4096];
44 analysis_limit
= TIME_LIMIT
;
47 st_computer_color
= BLACK
;
61 /* register engine commands */
64 /* register engine variables */
68 log
= fopen("rattatechess.log", "w");
74 board
.set_as_default();
79 unsigned char Engine::color_to_move()
81 return board
.color_to_move
;
84 unsigned char Engine::computer_color()
86 return st_computer_color
;
89 int Engine::get_status()
94 int Engine::move_number()
96 return board
.num_moves
;
101 st_computer_color
= board
.color_to_move
;
103 status_string
= NULL
;
104 eng_status
= PLAYING
;
105 //output("starting!\n");
110 void Engine::start(unsigned char color
)
112 st_computer_color
= color
;
114 status_string
= NULL
;
115 eng_status
= PLAYING
;
122 st_computer_color
= 0;
123 eng_status
= FORCING
;
128 void Engine::analyze()
130 st_computer_color
= 0;
131 HashKey h
= board
.hash
;
134 /* exited analyzing without any move being done?
135 (because of a near mate or a book entry found) */
136 while(eng_status
==ANALYZING
&& h
== board
.hash
)
140 void Engine::do_ponder()
142 HashKey h
= board
.hash
;
145 /* exited pondering without any move being done?
146 (because of a near mate or a book entry found) */
147 while(ponder
&& eng_status
==PLAYING
&&
148 st_computer_color
== board
.other_color
&& h
== board
.hash
)
152 void Engine::move_now()
156 output("You cannot use this command now!\n");
163 /* do the move and update a couple of things */
164 void Engine::move(Move mv
)
166 /* save the move in the stack of played moves (from the starting position) */
167 mv_done
[mv_done_num
++] = mv
;
169 board
.do_move(mv
, save_buf
[save_buf_num
++]);
171 if(board
.insufficient_material())
174 status_string
= "Insufficient material";
179 if(board
.fifty
>= 100)
182 status_string
= "Drawn by 50-move rule";
186 /* draw by 3fold repetition */
187 if(check_repetition(3))
190 status_string
= "Drawn by 3-fold repetition";
195 if(board
.find_moves(mvs
)==0) //mate or stalemate...
197 if(board
.under_check
)
199 if(board
.color_to_move
==WHITE
)
202 status_string
= "Black mates";
207 status_string
= "White mates";
213 status_string
= "Stalemate";
219 void Engine::retract_move()
223 board
.undo_move(mv_done
[--mv_done_num
], save_buf
[--save_buf_num
]);
224 board
.undo_move(mv_done
[--mv_done_num
], save_buf
[--save_buf_num
]);
231 board
.undo_move(mv_done
[--mv_done_num
], save_buf
[--save_buf_num
]);
235 void Engine::new_game()
238 analysis_limit
= TIME_LIMIT
;
240 st_computer_color
= BLACK
;
242 eng_status
= PLAYING
;
244 strcpy(opponent
, "<unknown>");
248 board
.set_as_default();
252 void Engine::set_depth(int d
)
254 analysis_limit
= DEPTH_LIMIT
;
258 void Engine::set_max_nodes(int d
)
260 analysis_limit
= NODES_LIMIT
;
264 void Engine::set_time_fixed(int t
)
266 analysis_limit
= TIME_LIMIT
;
270 void Engine::set_time_control(int mps
, int basesec
, int inc
)
272 analysis_limit
= TIME_LIMIT
;
277 time_clock_csec
= time_base
*100;
280 void Engine::set_my_clock(int t
)
285 void Engine::set_other_clock(int t
)
287 time_oth_clock_csec
= t
;
290 void Engine::print_board()
295 void Engine::read_board(char* brd
, char* color
, char* castle
,
296 char* passing
, int moves_to_draw
, int num_moves
)
298 board
.read_board(brd
, color
,castle
,passing
,moves_to_draw
,num_moves
);
305 void Engine::read_board(char* str
)
307 board
.read_board(str
);
314 void Engine::read_board(FILE* f
)
318 board
.read_board(str
);
321 void Engine::write_board(FILE* f
)
323 fputs( board
.to_fen(BigStr().data()), f
);
326 bool Engine::check_time()
330 if( eng_status
== PLAYING
&&
331 analysis_limit
== NODES_LIMIT
&&
332 processed_nodes
> (unsigned int)st_nodes
)
335 if( (processed_nodes
%4096) == 0 )
337 if( eng_status
== PLAYING
&&
338 analysis_limit
== TIME_LIMIT
&&
339 current_time()>=max_think_time
)
342 if(search_gui
) search_gui
->process_events();
344 if(input_available())
354 if(eng_status
== PLAYING
&& !ponder
355 && st_computer_color
== board
.other_color
)
358 while(input_available());
365 void Engine::calc_best_time()
368 time_best_csec
= time_fixed
* 100;
371 int nummoves
= (time_mps
== 0) ? 30 :
372 MAX((time_mps
- (board
.num_moves
% time_mps
)), 30);
373 time_best_csec
= time_clock_csec
/ nummoves
+ time_inc
* 100;
374 //time_best_csec = time_clock_csec / nummoves * (50 + rand()%300) / 200 + time_inc * 100;
378 uint64_t Engine::perft(int lev
)
382 num
= board
.find_moves(mv_stack
);
389 for(int i
=0;i
<num
;i
++)
391 board
.do_move(mv_stack
[i
], save_buf
[save_buf_num
++]);
393 board
.undo_move(mv_stack
[i
], save_buf
[--save_buf_num
]);
399 void Engine::autotune()
401 struct Tunable
{ const char* name
; int& param
; int start
; int end
; int step
; };
403 { "v_search_threat_threshold", v_search_threat_threshold
, 150, 720, 190 },
404 { "v_search_threat_extension", v_search_threat_extension
, 40, 120, 80 },
405 { "v_search_null_reduction", v_search_null_reduction
, 200, 400, 100 },
407 int numparams
= sizeof(data
)/sizeof(Tunable
);
410 for(int p
=0;p
<numparams
;p
++)
412 int oldv
= data
[p
].param
;
414 int best_goodness
= -1;
415 int worst_goodness
= 99999;
417 for(data
[p
].param
= data
[p
].start
; data
[p
].param
<= data
[p
].end
; data
[p
].param
+= data
[p
].step
)
420 for(int k
=0;k
<numparams
;k
++)
421 output("%s = %d%s\n", data
[k
].name
, data
[k
].param
, k
==p
? " <--" : "");
422 int goodness
= run_epd_prog("self", 1, "epd/abbe.epd");
423 if(goodness
> best_goodness
)
425 best_goodness
= goodness
;
426 best
= data
[p
].param
;
428 if(goodness
< worst_goodness
)
429 worst_goodness
= goodness
;
432 if(worst_goodness
== best_goodness
)
433 data
[p
].param
= oldv
;
435 data
[p
].param
= best
;
439 output("FINAL REPORT:\n");
440 for(int k
=0;k
<numparams
;k
++)
441 output("%s = %d\n", data
[k
].name
, data
[k
].param
);