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
[400];
38 save_buf
= new SaveBuf
[4096];
44 analysis_limit
= TIME_LIMIT
;
47 st_computer_color
= BLACK
;
59 /* register engine commands */
62 /* register engine variables */
66 log
= fopen("rattatechess.log", "w");
72 board
.set_as_default();
77 unsigned char Engine::color_to_move()
79 return board
.color_to_move
;
82 unsigned char Engine::computer_color()
84 return st_computer_color
;
87 int Engine::get_status()
92 int Engine::move_number()
94 return board
.num_moves
;
99 st_computer_color
= board
.color_to_move
;
101 status_string
= NULL
;
102 eng_status
= PLAYING
;
103 //output("starting!\n");
108 void Engine::start(unsigned char color
)
110 st_computer_color
= color
;
112 status_string
= NULL
;
113 eng_status
= PLAYING
;
120 st_computer_color
= 0;
121 eng_status
= FORCING
;
126 void Engine::analyze()
128 st_computer_color
= 0;
129 HashKey h
= board
.hash
;
132 /* exited analyzing without any move being done?
133 (because of a near mate or a book entry found) */
134 while(eng_status
==ANALYZING
&& h
== board
.hash
)
138 void Engine::do_ponder()
140 HashKey h
= board
.hash
;
143 /* exited pondering without any move being done?
144 (because of a near mate or a book entry found) */
145 while(ponder
&& eng_status
==PLAYING
&&
146 st_computer_color
== board
.other_color
&& h
== board
.hash
)
150 void Engine::move_now()
154 output("You cannot use this command now!\n");
161 /* do the move and update a couple of things */
162 void Engine::move(Move mv
)
164 /* save the move in the stack of played moves (from the starting position) */
165 mv_done
[mv_done_num
++] = mv
;
167 board
.do_move(mv
, save_buf
[save_buf_num
++]);
169 if(board
.insufficient_material())
172 status_string
= "Insufficient material";
177 if(board
.fifty
>= 100)
180 status_string
= "Drawn by 50-move rule";
184 /* draw by 3fold repetition */
185 if(check_repetition(3))
188 status_string
= "Drawn by 3-fold repetition";
193 if(board
.find_moves(mvs
)==0) //mate or stalemate...
195 if(board
.under_check
)
197 if(board
.color_to_move
==WHITE
)
200 status_string
= "Black mates";
205 status_string
= "White mates";
211 status_string
= "Stalemate";
217 void Engine::retract_move()
221 board
.undo_move(mv_done
[--mv_done_num
], save_buf
[--save_buf_num
]);
222 board
.undo_move(mv_done
[--mv_done_num
], save_buf
[--save_buf_num
]);
229 board
.undo_move(mv_done
[--mv_done_num
], save_buf
[--save_buf_num
]);
233 void Engine::new_game()
236 analysis_limit
= TIME_LIMIT
;
238 st_computer_color
= BLACK
;
240 eng_status
= PLAYING
;
242 strcpy(opponent
, "<unknown>");
246 board
.set_as_default();
250 void Engine::set_depth(int d
)
252 analysis_limit
= DEPTH_LIMIT
;
256 void Engine::set_max_nodes(int d
)
258 analysis_limit
= NODES_LIMIT
;
262 void Engine::set_time_fixed(int t
)
264 analysis_limit
= TIME_LIMIT
;
268 void Engine::set_time_control(int mps
, int basesec
, int inc
)
270 analysis_limit
= TIME_LIMIT
;
275 time_clock_csec
= time_base
*100;
278 void Engine::set_my_clock(int t
)
283 void Engine::set_other_clock(int t
)
285 time_oth_clock_csec
= t
;
288 void Engine::print_board()
293 void Engine::read_board(char* brd
, char* color
, char* castle
,
294 char* passing
, int moves_to_draw
, int num_moves
)
296 board
.read_board(brd
, color
,castle
,passing
,moves_to_draw
,num_moves
);
303 void Engine::read_board(char* str
)
305 board
.read_board(str
);
312 void Engine::read_board(FILE* f
)
316 board
.read_board(str
);
319 void Engine::write_board(FILE* f
)
321 fputs( board
.to_fen(BigStr().data()), f
);
324 bool Engine::check_time()
328 if( eng_status
== PLAYING
&&
329 analysis_limit
== NODES_LIMIT
&&
330 processed_nodes
> (unsigned int)st_nodes
)
333 if( (processed_nodes
%4096) == 0 )
335 if( eng_status
== PLAYING
&&
336 analysis_limit
== TIME_LIMIT
&&
337 current_time()>=max_think_time
)
340 if(search_gui
) search_gui
->process_events();
342 if(input_available())
352 if(eng_status
== PLAYING
&& !ponder
353 && st_computer_color
== board
.other_color
)
356 while(input_available());
363 void Engine::calc_best_time()
366 time_best_csec
= time_fixed
* 100;
369 int nummoves
= (time_mps
== 0) ? 30 :
370 MAX((time_mps
- (board
.num_moves
% time_mps
)), 30);
371 time_best_csec
= time_clock_csec
/ nummoves
+ time_inc
* 100;
372 //time_best_csec = time_clock_csec / nummoves * (50 + rand()%300) / 200 + time_inc * 100;
376 uint64_t Engine::perft(int lev
)
380 num
= board
.find_moves(mv_stack
);
387 for(int i
=0;i
<num
;i
++)
389 board
.do_move(mv_stack
[i
], save_buf
[save_buf_num
++]);
391 board
.undo_move(mv_stack
[i
], save_buf
[--save_buf_num
]);
397 void Engine::autotune()
399 struct Tunable
{ const char* name
; int& param
; int start
; int end
; int step
; };
401 { "v_search_threat_threshold", v_search_threat_threshold
, 150, 720, 190 },
402 { "v_search_threat_extension", v_search_threat_extension
, 40, 120, 80 },
403 { "v_search_null_reduction", v_search_null_reduction
, 200, 400, 100 },
405 int numparams
= sizeof(data
)/sizeof(Tunable
);
408 for(int p
=0;p
<numparams
;p
++)
410 int oldv
= data
[p
].param
;
412 int best_goodness
= -1;
413 int worst_goodness
= 99999;
415 for(data
[p
].param
= data
[p
].start
; data
[p
].param
<= data
[p
].end
; data
[p
].param
+= data
[p
].step
)
418 for(int k
=0;k
<numparams
;k
++)
419 output("%s = %d%s\n", data
[k
].name
, data
[k
].param
, k
==p
? " <--" : "");
420 int goodness
= run_epd_prog("self", 1, "epd/abbe.epd");
421 if(goodness
> best_goodness
)
423 best_goodness
= goodness
;
424 best
= data
[p
].param
;
426 if(goodness
< worst_goodness
)
427 worst_goodness
= goodness
;
430 if(worst_goodness
== best_goodness
)
431 data
[p
].param
= oldv
;
433 data
[p
].param
= best
;
437 output("FINAL REPORT:\n");
438 for(int k
=0;k
<numparams
;k
++)
439 output("%s = %d\n", data
[k
].name
, data
[k
].param
);