Basic (experimental) lazy evaluation
[owl.git] / iterate.c
blobad40f32f7e0cd321a1d2bcf309dc62579663ecec
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 */
29 int fail_high_root; /* fail high at first ply */
30 int leave_book;
31 int safe_search;
33 /* iterative deeping */
34 int
35 iterate(void)
37 int engine_xboard;
38 int best_move;
39 int best_score;
40 int best_depth;
41 int i_depth;
42 int score;
43 int start_time;
44 struct moves_t moves;
45 char pv_string[MAX_PV_STRING_SIZE];
47 start_time = get_time();
49 int max_time = get_engine_value(&e.max_time);
50 int time_bonus = leave_book == 1? max_time : 0;
52 set_engine_value((int *)&e.stop_time, start_time + \
53 max_time + time_bonus); /* when stop search */
54 set_engine_value((int *)&e.max_stop_time, start_time + \
55 e.max_time * 3 + time_bonus); /* when stop longest search */
57 /* initialize some data */
58 ZERO_MEM(pv);
59 ZERO_MEM(pv_length);
60 ZERO_MEM(history);
61 ZERO_MEM(killers);
62 ZERO_MEM(hash_moves);
63 ZERO_MEM(counters);
65 best_move = 0;
66 best_score = -MATE_VALUE;
67 best_depth = 0;
68 abort_search = FALSE;
69 fail_high_root = FALSE;
71 #ifdef CONSOLE_DEBUG
72 char fen_position[256];
73 fprintf(stdout, "setboard %s\n", current_fen_position(fen_position));
74 #endif
76 engine_xboard = get_engine_value(&e.xboard_mode);
77 /* if we have the only one move, don't think about it */
78 if (gen_legal_moves(&moves) == 1)
79 return moves.move[0];
81 if (!engine_xboard)
82 printf("ply nodes score pv\n");
84 hashtable_age++;
85 safe_search = FALSE;
87 for (i_depth = 1; i_depth <= get_engine_value(&e.max_depth); i_depth++) {
88 follow_pv = TRUE;
89 score = search_root(-MATE_VALUE, +MATE_VALUE, i_depth, \
90 IS_CHECKED(brd.wtm));
92 if (abort_search)
93 break;
95 /* save best move from last successful iteration */
96 best_move = pv[0][0];
97 best_score = score;
98 best_depth = i_depth;
100 /* get string PV representation (for 'Show Thinking' option or console
101 output) */
102 if (get_engine_value(&e.san_notation) || !engine_xboard)
103 get_pv_string_san(pv_string);
104 else
105 get_pv_string_coord(pv_string);
107 assert(score >= -MATE_VALUE && score <= MATE_VALUE);
109 if (!engine_xboard && pv[0][0])
110 fprintf(stdout, "%3d %10llu %5s%.2f %5u %s", i_depth, \
111 counters.searched_nodes, score >= 0? "+" : "-", \
112 abs(score) / (float)100, get_time() - start_time, pv_string);
113 else if (engine_xboard && get_engine_value(&e.post_mode) && \
114 ((i_depth > 5) || SCORE_IS_MATE(score))) {
115 fprintf(stdout, "%3d %7d %5u %10llu %s", i_depth, score, \
116 get_time() - start_time, counters.searched_nodes, pv_string);
119 if (SCORE_IS_MATE(score) && i_depth > 1)
120 /* don't search further if we have confirmed mate */
121 break;
122 /* if it's not fixed time search and we used more than 50% of the
123 required time */
124 if (!get_engine_value(&e.fixed_time) && ((get_time() - start_time) / \
125 (double)(get_engine_value((int *)&e.stop_time) - start_time) > 0.5))
126 break;
127 /* if it's not fixed time search and we used more than 30% of the
128 required time */
129 if (!get_engine_value(&e.fixed_time) && ((get_time() - start_time) / \
130 (double)(get_engine_value((int *)&e.stop_time) - start_time) > 0.33))
131 safe_search = TRUE;
134 if (get_engine_value(&e.play_computer) && get_engine_value(&e.post_mode))
135 fprintf(stdout, "tellics kibitz %.2f [%d], %dkNPS, PV = %s", (double)
136 best_score/100, best_depth, (int)((counters.searched_nodes/ 1000) / ((get_time() -
137 start_time) / (double)100)), pv_string);
139 /* should we resign? */
140 if (get_engine_value(&e.resign) && (best_score <= \
141 get_engine_value(&e.resign_value))) {
142 if (++e.hopeless_moves >= 3)
143 return -1;
144 } else
145 e.hopeless_moves = 0;
147 #ifdef CONSOLE_DEBUG
148 print_stats(get_time() - start_time);
149 #endif
150 return best_move;