Subversion Repositories Games.Chess Giants

Rev

Rev 108 | 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 01/17/09 */
  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.   int *mvp, *lastm, rmoves[256], sort_value[256];
  17.   int i, done, temp, value;
  18.   TREE *const tree = block[0];
  19. #if !defined(NOEGTB)
  20.   int mating_via_tb = 0, 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.     if (tb_value > 32000)
  48.       mating_via_tb = -tb_value - 1;
  49.   }
  50. #endif
  51. /*
  52.  ************************************************************
  53.  *                                                          *
  54.  *  First, use GenerateMoves() to generate the set of legal *
  55.  *  moves from the root position.                           *
  56.  *                                                          *
  57.  ************************************************************
  58.  */
  59.   lastm = GenerateCaptures(tree, 1, wtm, rmoves);
  60.   lastm = GenerateNoncaptures(tree, 1, wtm, lastm);
  61.   n_root_moves = lastm - rmoves;
  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.   for (mvp = rmoves; mvp < lastm; mvp++) {
  77.     value = -4000000;
  78. #if defined(TRACE)
  79.     if (trace_level >= 1) {
  80.       tree->curmv[1] = *mvp;
  81.       tree->phase[1] = HASH_MOVE;
  82.       Trace(tree, 1, 0, wtm, -MATE, MATE, "RootMoves()", tree->phase[1]);
  83.     }
  84. #endif
  85.     MakeMove(tree, 1, *mvp, wtm);
  86.     tree->nodes_searched++;
  87.     if (!Check(wtm))
  88.       do {
  89.         tree->curmv[1] = *mvp;
  90. #if !defined(NOEGTB)
  91.         if (TotalAllPieces <= EGTBlimit && EGTB_draw &&
  92.             Castle(1, white) + Castle(1, black) == 0) {
  93.           i = EGTBProbe(tree, 2, Flip(wtm), &tb_value);
  94.           if (i && tb_value != DrawScore(Flip(wtm)))
  95.             break;
  96.         }
  97.         if (mating_via_tb && TotalAllPieces <= EGTBlimit &&
  98.             Castle(1, white) + Castle(1, black) == 0) {
  99.           i = EGTBProbe(tree, 2, Flip(wtm), &tb_value);
  100.           if (i && ((mating_via_tb > DrawScore(Flip(wtm))
  101.                       && tb_value < mating_via_tb)
  102.                   || (mating_via_tb < DrawScore(Flip(wtm))
  103.                       && tb_value > mating_via_tb)))
  104.             break;
  105.         }
  106. #endif
  107.         value = -Quiesce(tree, -MATE, MATE, Flip(wtm), 2, 0);
  108. /*
  109.  ************************************************************
  110.  *                                                          *
  111.  *  Add in a bonus if this move is part of the previous     *
  112.  *  principal variation.  It was good in the search, we     *
  113.  *  should try it first now.                                *
  114.  *                                                          *
  115.  ************************************************************
  116.  */
  117.         if ((Piece(*mvp) == Piece(last_pv.path[1]))
  118.             && (From(*mvp) == From(last_pv.path[1]))
  119.             && (To(*mvp) == To(last_pv.path[1]))
  120.             && (Captured(*mvp) == Captured(last_pv.path[1]))
  121.             && (Promote(*mvp) == Promote(last_pv.path[1])))
  122.           value += 2000000;
  123. /*
  124.  ************************************************************
  125.  *                                                          *
  126.  *  Fudge the score for promotions so that promotion to a   *
  127.  *  queen is tried first.                                   *
  128.  *                                                          *
  129.  ************************************************************
  130.  */
  131.         if (Promote(*mvp) && (Promote(*mvp) != queen))
  132.           value -= 50;
  133.       } while (0);
  134.     sort_value[mvp - rmoves] = value;
  135.     UnmakeMove(tree, 1, *mvp, wtm);
  136.   }
  137. /*
  138.  ************************************************************
  139.  *                                                          *
  140.  *  Sort the moves into order based on the scores returned  *
  141.  *  by Quiesce() which includes evaluation + captures.      *
  142.  *                                                          *
  143.  ************************************************************
  144.  */
  145.   do {
  146.     done = 1;
  147.     for (i = 0; i < lastm - rmoves - 1; i++) {
  148.       if (sort_value[i] < sort_value[i + 1]) {
  149.         temp = sort_value[i];
  150.         sort_value[i] = sort_value[i + 1];
  151.         sort_value[i + 1] = temp;
  152.         temp = rmoves[i];
  153.         rmoves[i] = rmoves[i + 1];
  154.         rmoves[i + 1] = temp;
  155.         done = 0;
  156.       }
  157.     }
  158.   } while (!done);
  159. /*
  160.  ************************************************************
  161.  *                                                          *
  162.  *  Trim the move list to eliminate those moves that hang   *
  163.  *  the king and are illegal.  This also culls any non-     *
  164.  *  drawing moves when we are in the swindle-mode situation *
  165.  *  and want to do a normal search but only on moves that   *
  166.  *  preserve the draw.                                      *
  167.  *                                                          *
  168.  ************************************************************
  169.  */
  170.   for (; n_root_moves; n_root_moves--)
  171.     if (sort_value[n_root_moves - 1] > -3000000)
  172.       break;
  173.   if (sort_value[0] > 1000000)
  174.     sort_value[0] -= 2000000;
  175. /*
  176.  ************************************************************
  177.  *                                                          *
  178.  *  Debugging output to dump root move list and the stuff   *
  179.  *  used to sort them, for testing and debugging.           *
  180.  *                                                          *
  181.  ************************************************************
  182.  */
  183.   if (display_options & 512) {
  184.     Print(512, "%d moves at root\n", n_root_moves);
  185.     Print(512, "        move   score\n");
  186.     for (i = 0; i < n_root_moves; i++) {
  187.       tree->curmv[1] = rmoves[i];
  188.       Print(512, "%12s", OutputMove(tree, rmoves[i], 1, wtm));
  189.       Print(512, "%8d\n", sort_value[i]);
  190.     }
  191.   }
  192. /*
  193.  ************************************************************
  194.  *                                                          *
  195.  *  Check to see if we are in the special mode where moves  *
  196.  *  need to be searched because of missing EGTBs.  This is  *
  197.  *  sorto fo a hack that handles the case where we have an  *
  198.  *  EGTB file like KRPKR, but we don't have the files for   *
  199.  *  promotions for the pawn.  The program would avoid any   *
  200.  *  pawn promotion since it likely could not see the mate,  *
  201.  *  because the EGTB position does have a mate score.  In   *
  202.  *  this case, we turn EGTBs off for this search so that we *
  203.  *  can see a reason to promote the pawn and make progress  *
  204.  *  rather than just sitting on our pawn advantage.         *
  205.  *                                                          *
  206.  ************************************************************
  207.  */
  208. #if !defined(NOEGTB)
  209.   if (mating_via_tb) {
  210.     for (i = 0; i < n_root_moves; i++) {
  211.       tree->curmv[1] = rmoves[i];
  212.       MakeMove(tree, 1, rmoves[i], wtm);
  213.       if (mating_via_tb && TotalAllPieces <= EGTBlimit &&
  214.           Castle(1, white) + Castle(1, black) == 0)
  215.         temp =
  216.             (EGTBProbe(tree, 2, Flip(wtm),
  217.                 &tb_value) != DrawScore(Flip(wtm)));
  218.       else
  219.         temp = 0;
  220.       UnmakeMove(tree, 1, rmoves[i], wtm);
  221.       if (temp)
  222.         break;
  223.     }
  224.     EGTB_search = (i == n_root_moves);
  225.   } else
  226.     EGTB_search = 0;
  227. #endif
  228. /*
  229.  ************************************************************
  230.  *                                                          *
  231.  *  Copy the root moves into the root_move structure array  *
  232.  *  for use by NextRootMove().                              *
  233.  *                                                          *
  234.  ************************************************************
  235.  */
  236.   for (i = 0; i < n_root_moves; i++) {
  237.     root_moves[i].move = rmoves[i];
  238.     root_moves[i].status = 4;
  239.     root_moves[i].bm_age = 0;
  240.   }
  241.   root_moves[0].status = 0;
  242.   return;
  243. }
  244.