Subversion Repositories Games.Chess Giants

Rev

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

Rev Author Line No. Line
33 pmbaty 1
#include "chess.h"
2
#include "data.h"
3
#include "epdglue.h"
108 pmbaty 4
/* last modified 04/21/15 */
33 pmbaty 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];
108 pmbaty 17
  unsigned mvp, *lastm, rmoves[256];
18
  int temp, value;
33 pmbaty 19
#if !defined(NOEGTB)
108 pmbaty 20
  int tb_value;
33 pmbaty 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;
108 pmbaty 60
  for (mvp = 0; mvp < (unsigned int) n_root_moves; mvp++) // Pierre-Marie Baty -- added type cast
61
    root_moves[mvp].move = rmoves[mvp];
33 pmbaty 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
 */
108 pmbaty 76
  abort_search = 0;
77
  for (mvp = 0; mvp < (unsigned int) n_root_moves; mvp++) { // Pierre-Marie Baty -- added type cast
33 pmbaty 78
    value = -4000000;
79
#if defined(TRACE)
80
    if (trace_level >= 1) {
108 pmbaty 81
      tree->curmv[1] = root_moves[mvp].move;
82
      Trace(tree, 1, 0, wtm, -MATE, MATE, "RootMoves()", serial, HASH,
83
          mvp + 1);
33 pmbaty 84
    }
85
#endif
108 pmbaty 86
    MakeMove(tree, 1, wtm, root_moves[mvp].move);
33 pmbaty 87
    tree->nodes_searched++;
88
    if (!Check(wtm))
89
      do {
108 pmbaty 90
        tree->curmv[1] = root_moves[mvp].move;
33 pmbaty 91
#if !defined(NOEGTB)
92
        if (TotalAllPieces <= EGTBlimit && EGTB_draw &&
93
            Castle(1, white) + Castle(1, black) == 0) {
108 pmbaty 94
          temp = EGTBProbe(tree, 2, Flip(wtm), &tb_value);
95
          if (temp && tb_value != DrawScore(Flip(wtm)))
33 pmbaty 96
            break;
97
        }
98
#endif
108 pmbaty 99
        value = -Quiesce(tree, 2, Flip(wtm), -MATE, MATE, 0);
33 pmbaty 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
 */
108 pmbaty 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])))
33 pmbaty 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
 */
108 pmbaty 123
        if (Promote(root_moves[mvp].move) &&
124
            (Promote(root_moves[mvp].move) != queen))
33 pmbaty 125
          value -= 50;
126
      } while (0);
108 pmbaty 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);
33 pmbaty 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
 */
108 pmbaty 141
  SortRootMoves();
33 pmbaty 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--)
108 pmbaty 154
    if (root_moves[n_root_moves - 1].path.pathv > -3000000)
33 pmbaty 155
      break;
108 pmbaty 156
  if (root_moves[0].path.pathv > 1000000)
157
    root_moves[0].path.pathv -= 2000000;
33 pmbaty 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
 */
108 pmbaty 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));
33 pmbaty 172
  }
173
/*
174
 ************************************************************
175
 *                                                          *
108 pmbaty 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. *
33 pmbaty 180
 *                                                          *
181
 ************************************************************
182
 */
108 pmbaty 183
  for (mvp = 1; mvp < (unsigned int) n_root_moves; mvp++) // Pierre-Marie Baty -- added type cast
184
    root_moves[mvp].path.pathv = -99999999;
33 pmbaty 185
  return;
186
}