Subversion Repositories Games.Chess Giants

Rev

Rev 108 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 108 Rev 154
Line 2... Line 2...
2
#include "data.h"
2
#include "data.h"
3
#include "epdglue.h"
3
#include "epdglue.h"
-
 
4
#if defined(SYZYGY)
-
 
5
#  include "tbprobe.h"
-
 
6
#endif
4
/* last modified 04/21/15 */
7
/* last modified 07/11/16 */
5
/*
8
/*
6
 *******************************************************************************
9
 *******************************************************************************
7
 *                                                                             *
10
 *                                                                             *
8
 *   RootMoveList() is used to set up the ply one move list.  It is a  more    *
11
 *   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   *
12
 *   accurate ordering of the move list than that done for plies deeper than   *
Line 12... Line 15...
12
 *                                                                             *
15
 *                                                                             *
13
 *******************************************************************************
16
 *******************************************************************************
14
 */
17
 */
15
void RootMoveList(int wtm) {
18
void RootMoveList(int wtm) {
16
  TREE *const tree = block[0];
19
  TREE *const tree = block[0];
-
 
20
  ROOT_MOVE rtemp;
17
  unsigned mvp, *lastm, rmoves[256];
21
  unsigned mvp, *lastm, rmoves[256];
18
  int temp, value;
22
  int value, done;
19
#if !defined(NOEGTB)
23
#if defined(SYZYGY)
20
  int tb_value;
24
  int tb_result, tb_root = -9;
21
#endif
25
#endif
22
 
26
 
23
/*
27
/*
24
 ************************************************************
28
 ************************************************************
25
 *                                                          *
29
 *                                                          *
Line 34... Line 38...
34
 *  the best move (based on search/eval) that preserves the *
38
 *  the best move (based on search/eval) that preserves the *
35
 *  draw.                                                   *
39
 *  draw.                                                   *
36
 *                                                          *
40
 *                                                          *
37
 ************************************************************
41
 ************************************************************
38
 */
42
 */
39
#if !defined(NOEGTB)
43
#if defined(SYZYGY)
40
  EGTB_draw = 0;
44
  EGTB_draw = 0;
-
 
45
  if (swindle_mode) {
41
  if (EGTBlimit && TotalAllPieces <= EGTBlimit &&
46
    if (EGTBlimit && TotalAllPieces <= EGTBlimit &&
42
      Castle(1, white) + Castle(1, black) == 0 &&
47
        Castle(1, white) + Castle(1, black) == 0) {
-
 
48
      tb_result =
-
 
49
          tb_probe_root(Occupied(white), Occupied(black),
-
 
50
          Kings(white) | Kings(black), Queens(white) | Queens(black),
-
 
51
          Rooks(white) | Rooks(black), Bishops(white) | Bishops(black),
-
 
52
          Knights(white) | Knights(black), Pawns(white) | Pawns(black),
-
 
53
          Reversible(1), 0, EnPassant(1), wtm, NULL);
43
      EGTBProbe(tree, 1, wtm, &tb_value)) {
54
      if (tb_result != TB_RESULT_FAILED) {
44
    if (swindle_mode && (tb_value == DrawScore(wtm)))
55
        tb_root = TB_GET_WDL(tb_result);
45
      if ((wtm && Material > 0) || (!wtm && Material < 0))
56
        if ((tb_root == TB_DRAW && MaterialSTM(wtm) > 0) ||
-
 
57
            (tb_root == TB_CURSED_WIN))
46
        EGTB_draw = 1;
58
          EGTB_draw = 1;
-
 
59
      }
-
 
60
    }
47
  }
61
  }
48
#endif
62
#endif
49
/*
63
/*
50
 ************************************************************
64
 ************************************************************
51
 *                                                          *
65
 *                                                          *
Line 55... Line 69...
55
 ************************************************************
69
 ************************************************************
56
 */
70
 */
57
  lastm = GenerateCaptures(tree, 1, wtm, rmoves);
71
  lastm = GenerateCaptures(tree, 1, wtm, rmoves);
58
  lastm = GenerateNoncaptures(tree, 1, wtm, lastm);
72
  lastm = GenerateNoncaptures(tree, 1, wtm, lastm);
59
  n_root_moves = lastm - rmoves;
73
  n_root_moves = lastm - rmoves;
60
  for (mvp = 0; mvp < (unsigned int) n_root_moves; mvp++) // Pierre-Marie Baty -- added type cast
74
  for (mvp = 0; mvp < n_root_moves; mvp++)
61
    root_moves[mvp].move = rmoves[mvp];
75
    root_moves[mvp].move = rmoves[mvp];
62
/*
76
/*
63
 ************************************************************
77
 ************************************************************
64
 *                                                          *
78
 *                                                          *
65
 *  Now make each move and use Quiesce() to analyze the     *
79
 *  Now make each move and use Quiesce() to analyze the     *
Line 72... Line 86...
72
 *  the end of the root move list.                          *
86
 *  the end of the root move list.                          *
73
 *                                                          *
87
 *                                                          *
74
 ************************************************************
88
 ************************************************************
75
 */
89
 */
76
  abort_search = 0;
90
  abort_search = 0;
77
  for (mvp = 0; mvp < (unsigned int) n_root_moves; mvp++) { // Pierre-Marie Baty -- added type cast
91
  for (mvp = 0; mvp < n_root_moves; mvp++) {
78
    value = -4000000;
92
    value = -4000000;
79
#if defined(TRACE)
93
#if defined(TRACE)
80
    if (trace_level >= 1) {
94
    if (trace_level >= 1) {
81
      tree->curmv[1] = root_moves[mvp].move;
95
      tree->curmv[1] = root_moves[mvp].move;
82
      Trace(tree, 1, 0, wtm, -MATE, MATE, "RootMoves()", serial, HASH,
96
      Trace(tree, 1, 0, wtm, -MATE, MATE, "RootMoves()", serial, HASH,
Line 86... Line 100...
86
    MakeMove(tree, 1, wtm, root_moves[mvp].move);
100
    MakeMove(tree, 1, wtm, root_moves[mvp].move);
87
    tree->nodes_searched++;
101
    tree->nodes_searched++;
88
    if (!Check(wtm))
102
    if (!Check(wtm))
89
      do {
103
      do {
90
        tree->curmv[1] = root_moves[mvp].move;
104
        tree->curmv[1] = root_moves[mvp].move;
91
#if !defined(NOEGTB)
105
#if defined(SYZYGY)
92
        if (TotalAllPieces <= EGTBlimit && EGTB_draw &&
106
        if (EGTB_draw && TotalAllPieces <= EGTBlimit &&
93
            Castle(1, white) + Castle(1, black) == 0) {
107
            Castle(2, white) + Castle(2, black) == 0) {
-
 
108
          tb_result =
-
 
109
              tb_probe_root(Occupied(white), Occupied(black),
-
 
110
              Kings(white) | Kings(black), Queens(white) | Queens(black),
-
 
111
              Rooks(white) | Rooks(black), Bishops(white) | Bishops(black),
-
 
112
              Knights(white) | Knights(black), Pawns(white) | Pawns(black),
94
          temp = EGTBProbe(tree, 2, Flip(wtm), &tb_value);
113
              Reversible(2), 0, EnPassant(2), Flip(wtm), NULL);
95
          if (temp && tb_value != DrawScore(Flip(wtm)))
114
          if (tb_result != TB_RESULT_FAILED) {
-
 
115
            tb_result = 4 - TB_GET_WDL(tb_result);
-
 
116
            if (tb_result < tb_root)
96
            break;
117
              break;
-
 
118
          }
97
        }
119
        }
98
#endif
120
#endif
99
        value = -Quiesce(tree, 2, Flip(wtm), -MATE, MATE, 0);
121
        value = -Quiesce(tree, 2, Flip(wtm), -MATE, MATE, 0);
100
/*
122
/*
101
 ************************************************************
123
 ************************************************************
Line 136... Line 158...
136
 *  Sort the moves into order based on the scores returned  *
158
 *  Sort the moves into order based on the scores returned  *
137
 *  by Quiesce() which includes evaluation + captures.      *
159
 *  by Quiesce() which includes evaluation + captures.      *
138
 *                                                          *
160
 *                                                          *
139
 ************************************************************
161
 ************************************************************
140
 */
162
 */
-
 
163
  do {
-
 
164
    done = 1;
-
 
165
    for (mvp = 0; mvp < n_root_moves - 1; mvp++) {
-
 
166
      if (root_moves[mvp].path.pathv < root_moves[mvp + 1].path.pathv) {
-
 
167
        rtemp = root_moves[mvp];
-
 
168
        root_moves[mvp] = root_moves[mvp + 1];
-
 
169
        root_moves[mvp + 1] = rtemp;
-
 
170
        done = 0;
-
 
171
      }
-
 
172
    }
141
  SortRootMoves();
173
  } while (!done);
142
/*
174
/*
143
 ************************************************************
175
 ************************************************************
144
 *                                                          *
176
 *                                                          *
145
 *  Trim the move list to eliminate those moves that hang   *
177
 *  Trim the move list to eliminate those moves that hang   *
146
 *  the king and are illegal.  This also culls any non-     *
178
 *  the king and are illegal.  This also culls any non-     *
Line 164... Line 196...
164
 ************************************************************
196
 ************************************************************
165
 */
197
 */
166
  if (display_options & 128) {
198
  if (display_options & 128) {
167
    Print(128, "%d moves at root\n", n_root_moves);
199
    Print(128, "%d moves at root\n", n_root_moves);
168
    Print(128, "     score    move/pv\n");
200
    Print(128, "     score    move/pv\n");
169
    for (mvp = 0; mvp < (unsigned int) n_root_moves; mvp++) // Pierre-Marie Baty -- added type cast
201
    for (mvp = 0; mvp < n_root_moves; mvp++)
170
      Print(128, "%10s    %s\n", DisplayEvaluation(root_moves[mvp].path.pathv,
202
      Print(128, "%10s    %s\n", DisplayEvaluation(root_moves[mvp].path.pathv,
171
              wtm), DisplayPath(tree, wtm, &root_moves[mvp].path));
203
              wtm), DisplayPath(tree, wtm, &root_moves[mvp].path));
172
  }
204
  }
173
/*
205
/*
174
 ************************************************************
206
 ************************************************************
Line 178... Line 210...
178
 *  as we sort the root move list after fail highs and lows *
210
 *  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. *
211
 *  the un-searched moves won't pop to the top of the list. *
180
 *                                                          *
212
 *                                                          *
181
 ************************************************************
213
 ************************************************************
182
 */
214
 */
183
  for (mvp = 1; mvp < (unsigned int) n_root_moves; mvp++) // Pierre-Marie Baty -- added type cast
215
  for (mvp = 1; mvp < n_root_moves; mvp++)
184
    root_moves[mvp].path.pathv = -99999999;
216
    root_moves[mvp].path.pathv = -MATE;
185
  return;
217
  return;
-
 
218
}
-
 
219
 
-
 
220
/* last modified 07/11/16 */
-
 
221
/*
-
 
222
 *******************************************************************************
-
 
223
 *                                                                             *
-
 
224
 *   RootMoveEGTB() is used to handle the case where we are using syzygy end-  *
-
 
225
 *   game tablebases and the root position is found in them.  We need to use   *
-
 
226
 *   the DTZ tables to play the best move we can find since the game outcome   *
-
 
227
 *   is known for each possible move at this point.  We return it in a manner  *
-
 
228
 *   similar to Book().                                                        *
-
 
229
 *                                                                             *
-
 
230
 *   Note:  This depends on RootMoveList() being called FIRST since it is the  *
-
 
231
 *   responsible party to note that we are drawn at the root according to EGTB *
-
 
232
 *   and if appropriate, it will let RootMoveEGTB() know this to activate      *
-
 
233
 *   "swindle mode" and play on with a search rather than an instant move.     *
-
 
234
 *                                                                             *
-
 
235
 *******************************************************************************
-
 
236
 */
-
 
237
int RootMoveEGTB(int wtm) {
-
 
238
#if defined(SYZYGY)
-
 
239
  TREE *const tree = block[0];
-
 
240
  int tb_result, result;
-
 
241
 
-
 
242
/*
-
 
243
 ************************************************************
-
 
244
 *                                                          *
-
 
245
 *  first, we need to find the best TB move.  Simply, this  *
-
 
246
 *  is the move that gives us the best result, even though  *
-
 
247
 *  it might be speculative in the case of choosing a       *
-
 
248
 *  "cursed win" which is still technically a draw if the   *
-
 
249
 *  opponent makes no errors.                               *
-
 
250
 *                                                          *
-
 
251
 ************************************************************
-
 
252
 */
-
 
253
  EGTB_use = EGTBlimit;
-
 
254
  if (EGTB_use <= 0)
-
 
255
    return 0;
-
 
256
  if (EGTB_draw && !puzzling && swindle_mode)
-
 
257
    EGTB_use = 0;
-
 
258
  if (EGTBlimit && !EGTB_use)
-
 
259
    Print(32, "Drawn at root, trying for swindle.\n");
-
 
260
  if (EGTB_use && TotalAllPieces <= EGTBlimit && !Castle(0, white) &&
-
 
261
      !Castle(0, black)) {
-
 
262
    tree->egtb_probes++;
-
 
263
    tb_result =
-
 
264
        tb_probe_root(Occupied(white), Occupied(black),
-
 
265
        Kings(white) | Kings(black), Queens(white) | Queens(black),
-
 
266
        Rooks(white) | Rooks(black), Bishops(white) | Bishops(black),
-
 
267
        Knights(white) | Knights(black), Pawns(white) | Pawns(black),
-
 
268
        Reversible(1), 0, EnPassant(1), wtm, NULL);
-
 
269
    if (tb_result != TB_RESULT_FAILED) {
-
 
270
      int value, piece, captured;
-
 
271
      unsigned cmove, omove;
-
 
272
 
-
 
273
      if (n_root_moves > 0) {
-
 
274
        tree->egtb_hits++;
-
 
275
        result = TB_GET_WDL(tb_result);
-
 
276
        switch (result) {
-
 
277
          case TB_LOSS:
-
 
278
            value = -TBWIN;
-
 
279
            break;
-
 
280
          case TB_WIN:
-
 
281
            value = TBWIN;
-
 
282
            break;
-
 
283
          case TB_BLESSED_LOSS:
-
 
284
            value = -3;
-
 
285
            break;
-
 
286
          case TB_DRAW:
-
 
287
            value = 0;
-
 
288
            break;
-
 
289
          case TB_CURSED_WIN:
-
 
290
            value = 3;
-
 
291
            break;
-
 
292
          default:
-
 
293
            value = TB_GET_DTZ(tb_result);;
-
 
294
            break;
-
 
295
        }
-
 
296
        if (result != TB_LOSS && result != TB_WIN) {
-
 
297
          if (MaterialSTM(wtm) > 0)
-
 
298
            value += 1;
-
 
299
          else if (MaterialSTM(wtm) < 0)
-
 
300
            value -= 1;
-
 
301
        }
-
 
302
        piece = abs(PcOnSq(TB_GET_FROM(tb_result)));
-
 
303
        captured = abs(PcOnSq(TB_GET_TO(tb_result)));
-
 
304
        cmove =
-
 
305
            TB_GET_FROM(tb_result) | (TB_GET_TO(tb_result) << 6) | (piece <<
-
 
306
            12) | (captured << 15);
-
 
307
        if (TB_GET_PROMOTES(tb_result))
-
 
308
          cmove |= (6 - TB_GET_PROMOTES(tb_result)) << 18;
-
 
309
        end_time = ReadClock();
-
 
310
        tree->pv[0].path[1] = cmove;
-
 
311
        tree->pv[0].pathl = 2;
-
 
312
        tree->pv[0].pathh = 4;
-
 
313
        tree->pv[0].pathd = 0;
-
 
314
        tree->pv[0].pathv = value;
-
 
315
        MakeMove(tree, 1, wtm, cmove);
-
 
316
        result = Mated(tree, 2, Flip(wtm));
-
 
317
        UnmakeMove(tree, 1, wtm, cmove);
-
 
318
        if (result == 1)
-
 
319
          tree->pv[0].pathv = MATE - 2;
-
 
320
        else if (result == 2)
-
 
321
          tree->pv[0].pathv = DrawScore(wtm);
-
 
322
/*
-
 
323
 ************************************************************
-
 
324
 *                                                          *
-
 
325
 *  If we are not mated and did not mate on the move, we    *
-
 
326
 *  flip the side on move and find the best TB move so that *
-
 
327
 *  we can show the expected reply in the PV.               *
-
 
328
 *                                                          *
-
 
329
 ************************************************************
-
 
330
 */
-
 
331
        else {
-
 
332
          MakeMove(tree, 1, wtm, cmove);
-
 
333
          tree->egtb_probes++;
-
 
334
          tb_result =
-
 
335
              tb_probe_root(Occupied(white), Occupied(black),
-
 
336
              Kings(white) | Kings(black), Queens(white) | Queens(black),
-
 
337
              Rooks(white) | Rooks(black), Bishops(white) | Bishops(black),
-
 
338
              Knights(white) | Knights(black), Pawns(white) | Pawns(black),
-
 
339
              Reversible(2), 0, EnPassant(2), Flip(wtm), NULL);
-
 
340
          if (tb_result != TB_RESULT_FAILED) {
-
 
341
            tree->egtb_hits++;
-
 
342
            piece = abs(PcOnSq(TB_GET_FROM(tb_result)));
-
 
343
            captured = abs(PcOnSq(TB_GET_TO(tb_result)));
-
 
344
            omove =
-
 
345
                TB_GET_FROM(tb_result) | (TB_GET_TO(tb_result) << 6) | (piece
-
 
346
                << 12) | (captured << 15);
-
 
347
            if (TB_GET_PROMOTES(tb_result))
-
 
348
              omove |= (6 - TB_GET_PROMOTES(tb_result)) << 18;
-
 
349
            end_time = ReadClock();
-
 
350
            tree->pv[0].path[2] = omove;
-
 
351
            tree->pv[0].pathl = 3;
-
 
352
          }
-
 
353
          UnmakeMove(tree, 1, wtm, cmove);
-
 
354
        }
-
 
355
      }
-
 
356
/*
-
 
357
 ************************************************************
-
 
358
 *                                                          *
-
 
359
 *  We now know the best move to play, and possibly the     *
-
 
360
 *  opponent's best response.  Display this info and then   *
-
 
361
 *  we wait for the next move to pop in.                    *
-
 
362
 *                                                          *
-
 
363
 ************************************************************
-
 
364
 */
-
 
365
      Print(2, "        depth     time       score   variation\n");
-
 
366
      if (n_root_moves == 0) {
-
 
367
        program_end_time = ReadClock();
-
 
368
        tree->pv[0].pathl = 0;
-
 
369
        tree->pv[0].pathd = 0;
-
 
370
        if (Check(wtm))
-
 
371
          value = -(MATE - 1);
-
 
372
        else
-
 
373
          value = DrawScore(wtm);
-
 
374
        Print(2, "                             Mated   (no moves)\n");
-
 
375
        tree->nodes_searched = 1;
-
 
376
        if (!puzzling)
-
 
377
          last_root_value = value;
-
 
378
        return 1;
-
 
379
      }
-
 
380
      DisplayPV(tree, 5, wtm, end_time - start_time, &tree->pv[0], 1);
-
 
381
      return 1;
-
 
382
    }
-
 
383
  }
-
 
384
#endif
-
 
385
  return 0;
186
}
386
}