Improve hashtable, add replacement strategies
[owl.git] / iterate.c
blob12a8f8164ded99eab5df9ab0abd96a17d42a48fb
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 "attacks.h"
18 #include "board.h"
19 #include "engine.h"
20 #include "move.h"
21 #include "search.h"
22 #include "trans.h"
24 #define MAX_PV_STRING_SIZE 2048
26 int follow_pv; /* if we are following PV searched by previous
27 iteration */
28 int abort_search; /* TRUE if search should be stopped by some reason */
30 /* iterative deeping */
31 int
32 iterate(void)
34 int engine_xboard;
35 int best_move;
36 int best_score;
37 int i_depth;
38 int score;
39 int start_time;
40 struct moves_t moves;
41 char pv_string[MAX_PV_STRING_SIZE];
43 start_time = get_time();
44 set_engine_value((int *)&e.stop_time, start_time + \
45 get_engine_value(&e.max_time)); /* when stop search */
47 /* initialize some data */
48 ZERO_MEM(pv);
49 ZERO_MEM(pv_length);
50 ZERO_MEM(history);
51 ZERO_MEM(killers);
52 ZERO_MEM(hash_moves);
53 ZERO_MEM(counters);
55 best_move = 0;
56 best_score = -MATE_VALUE;
57 abort_search = FALSE;
59 #ifdef CONSOLE_DEBUG
60 char fen_position[256];
61 fprintf(stdout, "setboard %s\n", current_fen_position(fen_position));
62 #endif
64 engine_xboard = get_engine_value(&e.xboard_mode);
65 /* if we have the only one move, don't think about it */
66 if (gen_legal_moves(&moves) == 1)
67 return moves.move[0];
69 if (!engine_xboard)
70 printf("ply nodes score pv\n");
72 hashtable_age++;
74 for (i_depth = 1; i_depth <= get_engine_value(&e.max_depth); i_depth++) {
75 follow_pv = TRUE;
76 score = search_root(-MATE_VALUE, +MATE_VALUE, i_depth, \
77 IS_CHECKED(brd.wtm));
79 if (abort_search)
80 break;
82 /* save best move from last successful iteration */
83 best_move = pv[0][0];
84 best_score = score;
86 /* get string PV representation (for 'Show Thinking' option or console
87 output) */
88 if (get_engine_value(&e.san_notation) || !engine_xboard)
89 get_pv_string_san(pv_string);
90 else
91 get_pv_string_coord(pv_string);
93 assert(score >= -MATE_VALUE && score <= MATE_VALUE);
95 if (!engine_xboard && pv[0][0])
96 fprintf(stdout, "%3d %10llu %5s%.2f %5u %s", i_depth, \
97 counters.searched_nodes, score >= 0? "+" : "-", \
98 abs(score) / (float)100, get_time() - start_time, pv_string);
99 else if (engine_xboard && get_engine_value(&e.post_mode) && \
100 ((i_depth > 5) || SCORE_IS_MATE(score)))
101 fprintf(stdout, "%3d %7d %5u %10llu %s", i_depth, score, \
102 get_time() - start_time, counters.searched_nodes, pv_string);
104 if (SCORE_IS_MATE(score) && i_depth > 1)
105 /* don't search further if we have confirmed mate */
106 break;
107 /* if it's not fixed time search and we used more than 50% of the
108 required time */
109 if (!get_engine_value(&e.fixed_time) && ((get_time() - start_time) / \
110 (double)get_engine_value(&e.max_time)) > 0.5)
111 break;
114 /* should we resign? */
115 if (get_engine_value(&e.resign) && (best_score <= \
116 get_engine_value(&e.resign_value))) {
117 if (++e.hopeless_moves >= 3)
118 return -1;
119 } else
120 e.hopeless_moves = 0;
122 #ifdef CONSOLE_DEBUG
123 print_stats(get_time() - start_time);
124 #endif
125 return best_move;