- #include "chess.h" 
- #include "data.h" 
- #include "epdglue.h" 
- /* last modified 05/12/15 */ 
- /* 
-  ******************************************************************************* 
-  *                                                                             * 
-  *   Iterate() is the routine used to drive the iterated search.  It           * 
-  *   repeatedly calls search, incrementing the search depth after each call,   * 
-  *   until either time is exhausted or the maximum set search depth is         * 
-  *   reached.                                                                  * 
-  *                                                                             * 
-  *   Crafty has several specialized modes that influence how moves are chosen  * 
-  *   and when.                                                                 * 
-  *                                                                             * 
-  *   (1) "mode tournament" is a special way of handling book moves.  Here we   * 
-  *   are dealing with pondering.  We play our move, and then we take all of    * 
-  *   the known book moves for the opponent (moves where we have an instant     * 
-  *   reply since they are in the book) and eliminate those from the set of     * 
-  *   root moves to search.  We do a short search to figure out which of those  * 
-  *   non-book moves is best, and then we ponder that move.  It will look like  * 
-  *   we are always out of book, but we are not.  We are just looking for one   * 
-  *   of two cases:  (i) The opponent's book runs out and he doesn't play the   * 
-  *   expected book line (which is normally a mistake), where this will give us * 
-  *   a good chance of pondering the move he will actually play (a non-book     * 
-  *   move) without sitting around and doing nothing until he takes us out of   * 
-  *   book;  (ii) Our book doesn't have a reasonable choice, so we do a search  * 
-  *   and ponder a better choice so again we are not wasting time.  The value   * 
-  *   of "mode" will be set to "tournament" to enable this.                     * 
-  *                                                                             * 
-  *   (2) "book random 0" tells the program to enumerate the list of known book * 
-  *   moves, but rather than playing one randomly, we do a shortened search and * 
-  *   use the normal move selection approach (which will, unfortunately, accept * 
-  *   many gambits that a normal book line would bypass as too risky.  But this * 
-  *   can also find a better book move in many positions, since many book lines * 
-  *   are not verified with computer searches.                                  * 
-  *                                                                             * 
-  *   Those modes are handled within Book() and Ponder() but they all use the   * 
-  *   same iterated search as is used for normal moves.                         * 
-  *                                                                             * 
-  ******************************************************************************* 
-  */ 
- int Iterate(int wtm, int search_type, int root_list_done) { 
-   TREE *const tree = block[0]; 
-   ROOT_MOVE temp_rm; 
-   int i, alpha, beta, current_rm = 0, force_print = 0; 
-   int value = 0, twtm, correct, correct_count, npc, cpl, max; 
-   unsigned int idle_time; 
-   char buff[32]; 
- #if (CPUS > 1) 
- # if defined(UNIX) // Pierre-Marie Baty -- missing conditional macro 
-   pthread_t pt; 
- # endif 
- #endif 
-   
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Initialize draw score.  This has to be done here since  * 
-  *  we don't know whether we are searching for black or     * 
-  *  white until we get to this point.                       * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   draw_score[black] = (wtm) ? -abs_draw_score : abs_draw_score; 
-   draw_score[white] = (wtm) ? abs_draw_score : -abs_draw_score; 
- #if defined(NODES) 
-   temp_search_nodes = search_nodes; 
- #endif 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Initialize statistical counters and such.               * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   abort_search = 0; 
-   book_move = 0; 
-   program_start_time = ReadClock(); 
-   start_time = ReadClock(); 
-   root_wtm = wtm; 
-   kibitz_depth = 0; 
-   tree->nodes_searched = 0; 
-   tree->fail_highs = 0; 
-   tree->fail_high_first_move = 0; 
-   parallel_splits = 0; 
-   parallel_splits_wasted = 0; 
-   parallel_aborts = 0; 
-   parallel_joins = 0; 
-   for (i = 0; i < (int) smp_max_threads; i++) { // Pierre-Marie Baty -- added type cast 
-     thread[i].max_blocks = 0; 
-     thread[i].tree = 0; 
-     thread[i].idle = 0; 
-     thread[i].terminate = 0; 
-   } 
-   thread[0].tree = block[0]; 
-   correct_count = 0; 
-   burp = 15 * 100; 
-   transposition_age = (transposition_age + 1) & 0x1ff; 
-   next_time_check = nodes_between_time_checks; 
-   tree->evaluations = 0; 
-   tree->egtb_probes = 0; 
-   tree->egtb_hits = 0; 
-   tree->extensions_done = 0; 
-   tree->qchecks_done = 0; 
-   tree->moves_fpruned = 0; 
-   tree->moves_mpruned = 0; 
-   for (i = 0; i < 16; i++) { 
-     tree->LMR_done[i] = 0; 
-     tree->null_done[i] = 0; 
-   } 
-   root_wtm = wtm; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  We do a quick check to see if this position has a known * 
-  *  book reply.  If not, we drop into the main iterated     * 
-  *  search, otherwise we skip to the bottom and return the  * 
-  *  move that Book() returned.                              * 
-  *                                                          * 
-  *  Note the "booking" exception below.  If you use the     * 
-  *  "book random 0" you instruct Crafty to enumerate the    * 
-  *  known set of book moves, and then initiate a normal     * 
-  *  iterated search, but with just those known book moves   * 
-  *  included in the root move list.  We therefore choose    * 
-  *  (based on a normal search / evaluation but with a lower * 
-  *  time limit) from the book moves given.                  * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   if (!root_list_done) 
-     RootMoveList(wtm); 
-   if (booking || !Book(tree, wtm)) 
-     do { 
-       if (abort_search) 
-         break; 
- #if !defined(NOEGTB) 
-       if (EGTB_draw && !puzzling && swindle_mode) 
-         EGTB_use = 0; 
-       else 
-         EGTB_use = EGTBlimit; 
-       if (EGTBlimit && !EGTB_use) 
-         Print(32, "Drawn at root, trying for swindle.\n"); 
- #endif 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  The first action for a real search is to generate the   * 
-  *  root move list if it has not already been done.  For    * 
-  *  some circumstances, such as a non-random book move      * 
-  *  search, we are given the root move list, which only     * 
-  *  contains the known book moves.  Those are all we need   * 
-  *  to search.  If there are no legal moves, it is either   * 
-  *  mate or draw depending on whether the side to move is   * 
-  *  in check or not (mate or stalemate.)                    * 
-  *                                                          * 
-  *  Why would there be already be a root move list?  See    * 
-  *  the two modes described at the top (mode tournament and * 
-  *  book random 0) which would have already inserted just   * 
-  *  the moves that should be searched.                      * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-       if (n_root_moves == 0) { 
-         program_end_time = ReadClock(); 
-         tree->pv[0].pathl = 0; 
-         tree->pv[0].pathd = 0; 
-         if (Check(wtm)) 
-           value = -(MATE - 1); 
-         else 
-           value = DrawScore(wtm); 
-         Print(2, "        depth     time       score   variation\n"); 
-         Print(2, "                                     (no moves)\n"); 
-         tree->nodes_searched = 1; 
-         if (!puzzling) 
-           last_root_value = value; 
-         return value; 
-       } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Now set the search time and iteratively call Search()   * 
-  *  to analyze the position deeper and deeper.  Note that   * 
-  *  Search() is called with an alpha/beta window roughly    * 
-  *  1/3 of a pawn wide, centered on the score last returned * 
-  *  by search.                                              * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-       TimeSet(search_type); 
-       iteration = 1; 
-       noise_block = 0; 
-       force_print = 0; 
-       if (last_pv.pathd > 1) { 
-         iteration = last_pv.pathd + 1; 
-         value = last_root_value; 
-         tree->pv[0] = last_pv; 
-         root_moves[0].path = tree->pv[0]; 
-         noise_block = 1; 
-         force_print = 1; 
-       } else 
-         difficulty = 100; 
-       Print(2, "        depth     time       score   variation (%d)\n", 
-           iteration); 
-       abort_search = 0; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Set the initial search bounds based on the last search  * 
-  *  or default values.                                      * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-       tree->pv[0] = last_pv; 
-       if (iteration > 1) { 
-         alpha = Max(-MATE, last_value - 16); 
-         beta = Min(MATE, last_value + 16); 
-       } else { 
-         alpha = -MATE; 
-         beta = MATE; 
-       } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If we are using multiple threads, and they have not     * 
-  *  been started yet, then start them now as the search is  * 
-  *  ready to begin.                                         * 
-  *                                                          * 
-  *  If we are using CPU affinity, we need to set this up    * 
-  *  for thread 0 since it could have changed since we       * 
-  *  initialized everything.                                 * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
- #if (CPUS > 1) 
-       if ((int) smp_max_threads > smp_threads + 1) { // Pierre-Marie Baty -- added type cast 
-         long proc; 
-   
-         initialized_threads = 1; 
-         Print(32, "starting thread"); 
-         for (proc = smp_threads + 1; proc < (int) smp_max_threads; proc++) { // Pierre-Marie Baty -- added type cast 
-           Print(32, " %d", proc); 
- #  if defined(UNIX) 
-           pthread_create(&pt, &attributes, ThreadInit, (void *) proc); 
- #  else 
-           NumaStartThread(ThreadInit, (void *) proc); 
- #  endif 
-           smp_threads++; 
-         } 
-         Print(32, " <done>\n"); 
-       } 
-       WaitForAllThreadsInitialized(); 
-       ThreadAffinity(smp_affinity); 
- #endif 
-       if (search_nodes) 
-         nodes_between_time_checks = (unsigned int) search_nodes; // Pierre-Marie Baty -- added type cast 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Main iterative-deepening loop starts here.  We either   * 
-  *  start at depth = 1, or if we are pondering and have a   * 
-  *  PV from the previous search, we use that to set the     * 
-  *  starting depth.                                         * 
-  *                                                          * 
-  *  First install the old PV into the hash table so that    * 
-  *  these moves will be searched first.  We do this since   * 
-  *  the last iteration done could have overwritten the PV   * 
-  *  as the last few root moves were searched.               * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-       for (; iteration <= MAXPLY - 5; iteration++) { 
-         twtm = wtm; 
-         for (i = 1; i < (int) tree->pv[0].pathl; i++) { 
-           if (!VerifyMove(tree, i, twtm, tree->pv[0].path[i])) { 
-             Print(2048, "ERROR, not installing bogus pv info at ply=%d\n", i); 
-             Print(2048, "not installing from=%d  to=%d  piece=%d\n", 
-                 From(tree->pv[0].path[i]), To(tree->pv[0].path[i]), 
-                 Piece(tree->pv[0].path[i])); 
-             Print(2048, "pathlen=%d\n", tree->pv[0].pathl); 
-             break; 
-           } 
-           HashStorePV(tree, twtm, i); 
-           MakeMove(tree, i, twtm, tree->pv[0].path[i]); 
-           twtm = Flip(twtm); 
-         } 
-         for (i--; i > 0; i--) { 
-           twtm = Flip(twtm); 
-           UnmakeMove(tree, i, twtm, tree->pv[0].path[i]); 
-         } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Now we call Search() and start the next search          * 
-  *  iteration.  We already have solid alpha/beta bounds set * 
-  *  up for the aspiration search.  When each iteration      * 
-  *  completes, these aspiration values are recomputed and   * 
-  *  used for the next iteration.                            * 
-  *                                                          * 
-  *  We need to set "nodes_between_time_checks" to a value   * 
-  *  that will force us to check the time reasonably often   * 
-  *  without wasting excessive time doing this check.  As    * 
-  *  the target time limit gets shorter, we shorten the      * 
-  *  interval between time checks to avoid burning time off  * 
-  *  of the clock unnecessarily.                             * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-         if (trace_level) { 
-           Print(32, "==================================\n"); 
-           Print(32, "=      search iteration %2d       =\n", iteration); 
-           Print(32, "==================================\n"); 
-         } 
-         if (tree->nodes_searched) { 
-           nodes_between_time_checks = 
-               nodes_per_second / (10 * Max(smp_max_threads, 1)); 
-           if (!analyze_mode) { 
-             if (time_limit < 1000) 
-               nodes_between_time_checks /= 10; 
-             if (time_limit < 100) 
-               nodes_between_time_checks /= 10; 
-           } else 
-             nodes_between_time_checks = Min(nodes_per_second, 1000000); 
-         } 
-         if (search_nodes) 
-           nodes_between_time_checks = (unsigned int) (search_nodes - tree->nodes_searched); // Pierre-Marie Baty -- added type cast 
-         nodes_between_time_checks = 
-             Min(nodes_between_time_checks, MAX_TC_NODES); 
-         next_time_check = nodes_between_time_checks; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  This loop will execute until we either run out of time  * 
-  *  or complete this iteration.  Since we can return to     * 
-  *  Iterate() multiple times during this iteration, due to  * 
-  *  multiple fail highs (and perhaps even an initial fail   * 
-  *  low) we stick in this loop until we have completed all  * 
-  *  root moves or TimeCheck() tells us it is time to stop.  * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-         failhi_delta = 16; 
-         faillo_delta = 16; 
-         for (i = 0; i < n_root_moves; i++) { 
-           if (i || iteration == 1) 
-             root_moves[i].path.pathv = -99999999; 
-           root_moves[i].status &= 4; 
-         } 
-         while (1) { 
-           if (smp_max_threads > 1) 
-             smp_split = 1; 
-           rep_index--; 
-           value = Search(tree, 1, iteration, wtm, alpha, beta, Check(wtm), 0); 
-           rep_index++; 
-           end_time = ReadClock(); 
-           if (abort_search) 
-             break; 
-           for (current_rm = 0; current_rm < n_root_moves; current_rm++) 
-             if (tree->pv[0].path[1] == root_moves[current_rm].move) 
-               break; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Check for the case where we get a score back that is    * 
-  *  greater than or equal to beta.  This is called a fail   * 
-  *  high condition and requires a re-search with a better   * 
-  *  (more optimistic) beta value so that we can discover    * 
-  *  just how good this move really is.                      * 
-  *                                                          * 
-  *  Note that each time we return here, we need to increase * 
-  *  the upper search bound (beta).  We have a value named   * 
-  *  failhi_delta that is initially set to 16 on the first   * 
-  *  fail high of a particular move.  We increase beta by    * 
-  *  this value each time we fail high.  However, each time  * 
-  *  we fail high, we also double this value so that we      * 
-  *  increase beta at an ever-increasing rate.  Small jumps  * 
-  *  at first let us detect marginal score increases while   * 
-  *  still allowing cutoffs for branches with excessively    * 
-  *  high scores.  But each re-search sees the margin double * 
-  *  which quickly increases the bound as needed.            * 
-  *                                                          * 
-  *  We also use ComputeDifficulty() to adjust the level of  * 
-  *  difficulty for this move since we might be changing our * 
-  *  mind at the root.  (If we are failing high on the first * 
-  *  root move we skip this update.)                         * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-           if (value >= beta) { 
-             beta = Min(beta + failhi_delta, MATE); 
-             failhi_delta *= 2; 
-             if (failhi_delta > 10 * PAWN_VALUE) 
-               failhi_delta = 99999; 
-             root_moves[current_rm].status &= 7; 
-             root_moves[current_rm].bm_age = 4; 
-             if ((root_moves[current_rm].status & 2) == 0) 
-               difficulty = ComputeDifficulty(difficulty, +1); 
-             root_moves[current_rm].status |= 2; 
-             DisplayFail(tree, 1, 5, wtm, end_time - start_time, 
-                 root_moves[current_rm].move, value, force_print); 
-             temp_rm = root_moves[current_rm]; 
-             for (i = current_rm; i > 0; i--) 
-               root_moves[i] = root_moves[i - 1]; 
-             root_moves[0] = temp_rm; 
-           } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Check for the case where we get a score back that is    * 
-  *  less than or equal to alpha.  This is called a fail     * 
-  *  low condition and requires a re-search with a better    * 
-  *  more pessimistic)) alpha value so that we can discover  * 
-  *  just how bad this move really is.                       * 
-  *                                                          * 
-  *  Note that each time we return here, we need to decrease * 
-  *  the lower search bound (alpha).  We have a value named  * 
-  *  faillo_delta that is initially set to 16 on the first   * 
-  *  fail low of a particular move.  We decrease alpha by    * 
-  *  this value each time we fail low.  However, each time   * 
-  *  we fail low, we also double this value so that we       * 
-  *  decrease alpha at an ever-increasing rate.  Small jumps * 
-  *  at first let us detect marginal score decreases while   * 
-  *  still allowing cutoffs for branches with excessively    * 
-  *  low scores.  But each re-search sees the margin double  * 
-  *  which quickly decreases the bound as needed.            * 
-  *                                                          * 
-  *  We also use ComputeDifficulty() to adjust the level of  * 
-  *  difficulty for this move since we are failing low on    * 
-  *  the first move at the root, and we don't want to stop   * 
-  *  before we have a chance to find a better one.           * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-           else if (value <= alpha) { 
-             alpha = Max(alpha - faillo_delta, -MATE); 
-             faillo_delta *= 2; 
-             if (faillo_delta > 10 * PAWN_VALUE) 
-               faillo_delta = 99999; 
-             root_moves[current_rm].status &= 7; 
-             if ((root_moves[current_rm].status & 1) == 0) 
-               difficulty = ComputeDifficulty(Max(100, difficulty), -1); 
-             root_moves[current_rm].status |= 1; 
-             DisplayFail(tree, 2, 5, wtm, end_time - start_time, 
-                 root_moves[current_rm].move, value, force_print); 
-           } else 
-             break; 
-         } 
-         if (value > alpha && value < beta) 
-           last_root_value = value; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If we are running a test suite, check to see if we can  * 
-  *  exit the search.  This happens when N successive        * 
-  *  iterations produce the correct solution.  N is set by   * 
-  *  the test command in Option().                           * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-         correct = solution_type; 
-         for (i = 0; i < number_of_solutions; i++) { 
-           if (!solution_type) { 
-             if (solutions[i] == tree->pv[0].path[1]) 
-               correct = 1; 
-           } else if (solutions[i] == root_moves[current_rm].move) 
-             correct = 0; 
-         } 
-         if (correct) 
-           correct_count++; 
-         else 
-           correct_count = 0; 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Notice that we don't search moves that were best over   * 
-  *  the last 3 iterations in parallel, nor do we reduce     * 
-  *  those since they are potential best moves again.        * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-         for (i = 0; i < n_root_moves; i++) { 
-           root_moves[i].status &= 3; 
-           if (root_moves[i].bm_age) 
-             root_moves[i].bm_age--; 
-           if (root_moves[i].bm_age) 
-             root_moves[i].status |= 4; 
-         } 
-         SortRootMoves(); 
-         difficulty = ComputeDifficulty(difficulty, 0); 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If requested, print the ply=1 move list along with the  * 
-  *  flags for each move.  Once we print this (if requested) * 
-  *  we can then clear all of the status flags (except the   * 
-  *  "do not search in parallel or reduce" flag) to prepare  * 
-  *  for the start of the next iteration, since that is the  * 
-  *  only flag that needs to be carried forward to the next  * 
-  *  iteration.                                              * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-         if (display_options & 64) { 
-           Print(64, "      rmove   score    age  S ! ?\n"); 
-           for (i = 0; i < n_root_moves; i++) { 
-             Print(64, " %10s ", OutputMove(tree, 1, wtm, root_moves[i].move)); 
-             if (root_moves[i].path.pathv > -MATE) 
-               Print(64, "%s", DisplayEvaluation(root_moves[i].path.pathv, 
-                       wtm)); 
-             else 
-               Print(64, "  -----"); 
-             Print(64, "     %d   %d %d %d\n", root_moves[i].bm_age, 
-                 (root_moves[i].status & 4) != 0, 
-                 (root_moves[i].status & 2) != 0, 
-                 (root_moves[i].status & 1) != 0); 
-           } 
-         } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Here we simply display the PV from the current search   * 
-  *  iteration, and then set the aspiration for the next     * 
-  *  iteration to the current score +/- 16.                  * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-         if (end_time - start_time > 10) 
-           nodes_per_second = (unsigned int) // Pierre-Marie Baty -- added type cast 
-               (tree->nodes_searched * 100 / (uint64_t) (end_time - start_time)); 
-         else 
-           nodes_per_second = 1000000; 
-         tree->pv[0] = root_moves[0].path; 
-         if (!abort_search && value != -(MATE - 1)) { 
-           if (end_time - start_time >= noise_level) { 
-             DisplayPV(tree, 5, wtm, end_time - start_time, &tree->pv[0], 
-                 force_print); 
-             noise_block = 0; 
-           } else 
-             noise_block = 1; 
-         } 
-         alpha = Max(-MATE, value - 16); 
-         beta = Min(MATE, value + 16); 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  There are multiple termination criteria that are used.  * 
-  *  The first and most obvious is that we have exceeded the * 
-  *  target time limit.  Others include reaching a user-set  * 
-  *  maximum search depth, finding a mate and we searched so * 
-  *  deep there is little chance of another iteration find-  * 
-  *  ing a shorter mate; the search was aborted due to some  * 
-  *  sort of user input (usually during pondering);  and     * 
-  *  finally, when running a test suite, we had the correct  * 
-  *  best move for N successive iterations and the user      * 
-  *  asked us to stop after that number.                     * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-         if (TimeCheck(tree, 0)) 
-           break; 
-         if (iteration > 3 && value > 32000 && value >= (MATE - iteration + 3) 
-             && value > last_mate_score) 
-           break; 
-         if ((iteration >= search_depth) && search_depth) 
-           break; 
-         if (abort_search) 
-           break; 
-         end_time = ReadClock() - start_time; 
-         if (correct_count >= early_exit) 
-           break; 
- #if !defined(NOEGTB) 
-         if (iteration > EGTB_depth + 10 && TotalAllPieces <= EGTBlimit && 
-             EGTB_use && EGTBProbe(tree, 1, wtm, &i)) 
-           break; 
- #endif 
-         if (search_nodes && tree->nodes_searched >= search_nodes) 
-           break; 
-       } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  Search done, now display statistics, depending on the   * 
-  *  display options set (see display command in Option().)  * 
-  *                                                          * 
-  *  Simple kludge here.  If the last search was quite deep  * 
-  *  while we were pondering, we start this iteration at the * 
-  *  last depth - 1.  Sometimes that will result in a search * 
-  *  that is deep enough that we do not produce/print a PV   * 
-  *  before time runs out.  On other occasions, noise_level  * 
-  *  prevents us from printing anything, leaving us with no  * 
-  *  output during this PV.  We initialize a variable named  * 
-  *  noise_block to 1.  If, during this iteration, we do     * 
-  *  manage to print a PV, we set it to zero until the next  * 
-  *  iteration starts.  Otherwise this will force us to at   * 
-  *  display the PV from the last iteration (first two moves * 
-  *  were removed in main(), so they are not present) so we  * 
-  *  have some sort of output for this iteration.            * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-       end_time = ReadClock(); 
-       if (end_time > 10) 
-         nodes_per_second = (unsigned int) // Pierre-Marie Baty -- added type cast 
-             ((uint64_t) tree->nodes_searched * 100 / Max((uint64_t) end_time - 
-             start_time, 1)); 
-       if (abort_search != 2 && !puzzling) { 
-         if (noise_block) 
-           DisplayPV(tree, 5, wtm, end_time - start_time, &tree->pv[0], 1); 
-         tree->evaluations = (tree->evaluations) ? tree->evaluations : 1; 
-         tree->fail_highs++; 
-         tree->fail_high_first_move++; 
-         idle_time = 0; 
-         for (i = 0; i < (int) smp_max_threads; i++) // Pierre-Marie Baty -- added type cast 
-           idle_time += thread[i].idle; 
-         busy_percent = 
-             100 - Min(100, 
-             100 * idle_time / (smp_max_threads * (end_time - start_time) + 
-                 1)); 
-         Print(8, "        time=%s(%d%%)", 
-             DisplayTimeKibitz(end_time - start_time), busy_percent); 
-         Print(8, "  nodes=%" PRIu64 "(%s)", tree->nodes_searched, 
-             DisplayKMB(tree->nodes_searched, 0)); 
-         Print(8, "  fh1=%d%%", 
-             tree->fail_high_first_move * 100 / tree->fail_highs); 
-         Print(8, "  pred=%d", predicted); 
-         Print(8, "  nps=%s\n", DisplayKMB(nodes_per_second, 0)); 
-         Print(8, "        chk=%s", DisplayKMB(tree->extensions_done, 0)); 
-         Print(8, "  qchk=%s", DisplayKMB(tree->qchecks_done, 0)); 
-         Print(8, "  fp=%s", DisplayKMB(tree->moves_fpruned, 0)); 
-         Print(8, "  mcp=%s", DisplayKMB(tree->moves_mpruned, 0)); 
-         Print(8, "  50move=%d", Reversible(0)); 
-         if (tree->egtb_hits) 
-           Print(8, "  egtb=%s", DisplayKMB(tree->egtb_hits, 0)); 
-         Print(8, "\n"); 
-         Print(8, "        LMReductions:"); 
-         npc = 21; 
-         cpl = 75; 
-         for (i = 1; i < 16; i++) 
-           if (tree->LMR_done[i]) { 
-             sprintf(- buff , "%d/%s",-  i ,-  DisplayKMB (- tree ->- LMR_done [- i ], 0));
 
-             if (- npc  + (int)strlen(- buff ) >-  cpl ) { // Pierre-Marie Baty -- added type cast
 
-               Print(8, "\n            "); 
-               npc = 12; 
-             } 
-             Print(8, "  %s", buff); 
-           } 
-         if (npc) 
-           Print(8, "\n"); 
-         npc = 24; 
-         cpl = 75; 
-         if (tree->null_done[null_depth]) 
-           Print(8, "        null-move (R):"); 
-         for (i = null_depth; i < 16; i++) 
-           if (tree->null_done[i]) { 
-             sprintf(- buff , "%d/%s",-  i ,-  DisplayKMB (- tree ->- null_done [- i ], 0));
 
-             if (- npc  + (int)strlen(- buff ) >-  cpl ) { // Pierre-Marie Baty -- added type cast
 
-               Print(8, "\n            "); 
-               npc = 12; 
-             } 
-             Print(8, "  %s", buff); 
-           } 
-         if (npc) 
-           Print(8, "\n"); 
-         if (parallel_splits) { 
-           max = 0; 
-           for (i = 0; i < (int) smp_max_threads; i++) { // Pierre-Marie Baty -- added type cast 
-             max = Max(max, PopCnt(thread[i].max_blocks)); 
-             game_max_blocks |= thread[i].max_blocks; 
-           } 
-           Print(8, "        splits=%s", DisplayKMB(parallel_splits, 0)); 
-           Print(8, "(%s)", DisplayKMB(parallel_splits_wasted, 0)); 
-           Print(8, "  aborts=%s", DisplayKMB(parallel_aborts, 0)); 
-           Print(8, "  joins=%s", DisplayKMB(parallel_joins, 0)); 
-           Print(8, "  data=%d%%(%d%%)\n", 100 * max / 64, 
-               100 * PopCnt(game_max_blocks) / 64); 
-         } 
-       } 
-     } while (0); 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If this is a known book position, Book() has already    * 
-  *  set the PV/best move so we can return without doing the * 
-  *  iterated search at all.                                 * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   else { 
-     last_root_value = 0; 
-     value = 0; 
-     book_move = 1; 
-     if (analyze_mode) 
-       Kibitz(4, wtm, 0, 0, 0, 0, 0, 0, kibitz_text); 
-   } 
- /* 
-  ************************************************************ 
-  *                                                          * 
-  *  If "smp_nice" is set, and we are not allowed to ponder  * 
-  *  while waiting on the opponent to move, then terminate   * 
-  *  the parallel threads so they won't sit in their normal  * 
-  *  spin-wait loop while waiting for new work which will    * 
-  *  "burn" smp_max_threads - 1 cpus, penalizing anything    * 
-  *  else that might be running (such as another chess       * 
-  *  engine we might be playing in a ponder=off match.)      * 
-  *                                                          * 
-  ************************************************************ 
-  */ 
-   if (smp_nice && ponder == 0 && smp_threads) { 
-     int proc; 
-   
-     Print(64, "terminating SMP processes.\n"); 
-     for (proc = 1; proc < CPUS; proc++) 
-       thread[proc].terminate = 1; 
-     while (smp_threads); 
-     smp_split = 0; 
-   } 
-   program_end_time = ReadClock(); 
-   search_move = 0; 
-   if (quit) 
-     CraftyExit(0); 
-   return last_root_value; 
- } 
-