Subversion Repositories Games.Chess Giants

Rev

Rev 33 | Rev 154 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "chess.h"
  2. #include "data.h"
  3. #include "epdglue.h"
  4. /* last modified 04/21/15 */
  5. /*
  6.  *******************************************************************************
  7.  *                                                                             *
  8.  *   RootMoveList() is used to set up the ply one move list.  It is a  more    *
  9.  *   accurate ordering of the move list than that done for plies deeper than   *
  10.  *   one.  Briefly, Quiesce() is used to obtain the positional score plus the  *
  11.  *   expected gain/loss for pieces that can be captured.                       *
  12.  *                                                                             *
  13.  *******************************************************************************
  14.  */
  15. void RootMoveList(int wtm) {
  16.   TREE *const tree = block[0];
  17.   unsigned mvp, *lastm, rmoves[256];
  18.   int temp, value;
  19. #if !defined(NOEGTB)
  20.   int tb_value;
  21. #endif
  22.  
  23. /*
  24.  ************************************************************
  25.  *                                                          *
  26.  *  If the position at the root is a draw, based on EGTB    *
  27.  *  results, we are going to behave differently.  We will   *
  28.  *  extract the root moves that are draws, and toss the     *
  29.  *  losers out.  Then, we will do a normal search on the    *
  30.  *  moves that draw to try and chose the drawing move that  *
  31.  *  gives our opponent the best chance to make an error.    *
  32.  *  This search will be done sans EGTB probes since we al-  *
  33.  *  ready know this is a draw at the root.  We simply find  *
  34.  *  the best move (based on search/eval) that preserves the *
  35.  *  draw.                                                   *
  36.  *                                                          *
  37.  ************************************************************
  38.  */
  39. #if !defined(NOEGTB)
  40.   EGTB_draw = 0;
  41.   if (EGTBlimit && TotalAllPieces <= EGTBlimit &&
  42.       Castle(1, white) + Castle(1, black) == 0 &&
  43.       EGTBProbe(tree, 1, wtm, &tb_value)) {
  44.     if (swindle_mode && (tb_value == DrawScore(wtm)))
  45.       if ((wtm && Material > 0) || (!wtm && Material < 0))
  46.         EGTB_draw = 1;
  47.   }
  48. #endif
  49. /*
  50.  ************************************************************
  51.  *                                                          *
  52.  *  First, use GenerateMoves() to generate the set of legal *
  53.  *  moves from the root position.                           *
  54.  *                                                          *
  55.  ************************************************************
  56.  */
  57.   lastm = GenerateCaptures(tree, 1, wtm, rmoves);
  58.   lastm = GenerateNoncaptures(tree, 1, wtm, lastm);
  59.   n_root_moves = lastm - rmoves;
  60.   for (mvp = 0; mvp < (unsigned int) n_root_moves; mvp++) // Pierre-Marie Baty -- added type cast
  61.     root_moves[mvp].move = rmoves[mvp];
  62. /*
  63.  ************************************************************
  64.  *                                                          *
  65.  *  Now make each move and use Quiesce() to analyze the     *
  66.  *  potential captures and return a minimax score.          *
  67.  *                                                          *
  68.  *  Special case:  if this is an egtb draw at the root,     *
  69.  *  then this is where we cull the non-drawing moves by     *
  70.  *  doing an EGTB probe for each move.  Any moves that lose *
  71.  *  are left with a very bad sorting score to move them to  *
  72.  *  the end of the root move list.                          *
  73.  *                                                          *
  74.  ************************************************************
  75.  */
  76.   abort_search = 0;
  77.   for (mvp = 0; mvp < (unsigned int) n_root_moves; mvp++) { // Pierre-Marie Baty -- added type cast
  78.     value = -4000000;
  79. #if defined(TRACE)
  80.     if (trace_level >= 1) {
  81.       tree->curmv[1] = root_moves[mvp].move;
  82.       Trace(tree, 1, 0, wtm, -MATE, MATE, "RootMoves()", serial, HASH,
  83.           mvp + 1);
  84.     }
  85. #endif
  86.     MakeMove(tree, 1, wtm, root_moves[mvp].move);
  87.     tree->nodes_searched++;
  88.     if (!Check(wtm))
  89.       do {
  90.         tree->curmv[1] = root_moves[mvp].move;
  91. #if !defined(NOEGTB)
  92.         if (TotalAllPieces <= EGTBlimit && EGTB_draw &&
  93.             Castle(1, white) + Castle(1, black) == 0) {
  94.           temp = EGTBProbe(tree, 2, Flip(wtm), &tb_value);
  95.           if (temp && tb_value != DrawScore(Flip(wtm)))
  96.             break;
  97.         }
  98. #endif
  99.         value = -Quiesce(tree, 2, Flip(wtm), -MATE, MATE, 0);
  100. /*
  101.  ************************************************************
  102.  *                                                          *
  103.  *  Add in a bonus if this move is part of the previous     *
  104.  *  principal variation.  It was good in the search, we     *
  105.  *  should try it first now.                                *
  106.  *                                                          *
  107.  ************************************************************
  108.  */
  109.         if ((Piece(root_moves[mvp].move) == Piece(last_pv.path[1]))
  110.             && (From(root_moves[mvp].move) == From(last_pv.path[1]))
  111.             && (To(root_moves[mvp].move) == To(last_pv.path[1]))
  112.             && (Captured(root_moves[mvp].move) == Captured(last_pv.path[1]))
  113.             && (Promote(root_moves[mvp].move) == Promote(last_pv.path[1])))
  114.           value += 2000000;
  115. /*
  116.  ************************************************************
  117.  *                                                          *
  118.  *  Fudge the score for promotions so that promotion to a   *
  119.  *  queen is tried first.                                   *
  120.  *                                                          *
  121.  ************************************************************
  122.  */
  123.         if (Promote(root_moves[mvp].move) &&
  124.             (Promote(root_moves[mvp].move) != queen))
  125.           value -= 50;
  126.       } while (0);
  127.     root_moves[mvp].path = tree->pv[1];
  128.     root_moves[mvp].path.pathv = value;
  129.     root_moves[mvp].status = 0;
  130.     root_moves[mvp].bm_age = 0;
  131.     UnmakeMove(tree, 1, wtm, root_moves[mvp].move);
  132.   }
  133. /*
  134.  ************************************************************
  135.  *                                                          *
  136.  *  Sort the moves into order based on the scores returned  *
  137.  *  by Quiesce() which includes evaluation + captures.      *
  138.  *                                                          *
  139.  ************************************************************
  140.  */
  141.   SortRootMoves();
  142. /*
  143.  ************************************************************
  144.  *                                                          *
  145.  *  Trim the move list to eliminate those moves that hang   *
  146.  *  the king and are illegal.  This also culls any non-     *
  147.  *  drawing moves when we are in the swindle-mode situation *
  148.  *  and want to do a normal search but only on moves that   *
  149.  *  preserve the draw.                                      *
  150.  *                                                          *
  151.  ************************************************************
  152.  */
  153.   for (; n_root_moves; n_root_moves--)
  154.     if (root_moves[n_root_moves - 1].path.pathv > -3000000)
  155.       break;
  156.   if (root_moves[0].path.pathv > 1000000)
  157.     root_moves[0].path.pathv -= 2000000;
  158. /*
  159.  ************************************************************
  160.  *                                                          *
  161.  *  Debugging output to dump root move list and the stuff   *
  162.  *  used to sort them, for testing and debugging.           *
  163.  *                                                          *
  164.  ************************************************************
  165.  */
  166.   if (display_options & 128) {
  167.     Print(128, "%d moves at root\n", n_root_moves);
  168.     Print(128, "     score    move/pv\n");
  169.     for (mvp = 0; mvp < (unsigned int) n_root_moves; mvp++) // Pierre-Marie Baty -- added type cast
  170.       Print(128, "%10s    %s\n", DisplayEvaluation(root_moves[mvp].path.pathv,
  171.               wtm), DisplayPath(tree, wtm, &root_moves[mvp].path));
  172.   }
  173. /*
  174.  ************************************************************
  175.  *                                                          *
  176.  *  Finally, before we return the list of moves, we need to *
  177.  *  set the values to an impossible negative value so that  *
  178.  *  as we sort the root move list after fail highs and lows *
  179.  *  the un-searched moves won't pop to the top of the list. *
  180.  *                                                          *
  181.  ************************************************************
  182.  */
  183.   for (mvp = 1; mvp < (unsigned int) n_root_moves; mvp++) // Pierre-Marie Baty -- added type cast
  184.     root_moves[mvp].path.pathv = -99999999;
  185.   return;
  186. }
  187.