Subversion Repositories Games.Chess Giants

Rev

Rev 108 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
108 pmbaty 1
#include "chess.h"
2
#include "data.h"
3
/* last modified 08/15/15 */
4
/*
5
 *******************************************************************************
6
 *                                                                             *
7
 *   History() is used to maintain the two killer moves for each ply.  The     *
8
 *   most recently used killer is always first in the list.                    *
9
 *                                                                             *
10
 *   History() also maintains two counter-moves.  These are moves that are     *
11
 *   directly used to refute a specific move at the previous ply, rather than  *
12
 *   just a plain killer that has caused cutoffs previously.                   *
13
 *                                                                             *
14
 *   History() finally remembers two moves that were played after a specific   *
15
 *   move at ply-2 (ie the two moves together create some sort of "plan".)     *
16
 *                                                                             *
17
 *   History() also maintains the history counters.  Each time a move fails    *
18
 *   high, it's history count is increased, while all other moves that were    *
19
 *   searched will have their counts reduced.  The current counter is a        *
20
 *   saturating counter in the range 0 <= N <= 2047.                           *
21
 *                                                                             *
22
 *******************************************************************************
23
 */
24
void History(TREE * RESTRICT tree, int ply, int depth, int side, int move,
25
    int searched[]) {
26
  int i, index, mindex;
27
/*
28
 ************************************************************
29
 *                                                          *
30
 *  Now, add this move to the current killer moves if it is *
31
 *  not already there.  If the move is already first in the *
32
 *  list, leave it there, otherwise move the first one down *
33
 *  to slot two and insert this move into slot one.         *
34
 *                                                          *
35
 *  If the best move so far is a capture or a promotion,    *
36
 *  we skip updating the killers (but still update history  *
37
 *  information) since we search good captures first, which *
38
 *  happens before killers are tried, making capture moves  *
39
 *  useless here.                                           *
40
 *                                                          *
41
 *  The update value does not depend on depth.  I used a    *
42
 *  function of depth for years, but as I examined more and *
43
 *  more trees, that seemed to be lacking because it gives  *
44
 *  a really large bias towards moves that work near the    *
45
 *  root, while most of the nodes searched are near the     *
46
 *  tips.  One unusual characteristic of this counter is    *
47
 *  that it is a software-based saturating counter.  That   *
48
 *  is, it can never exceed 2047, nor can it ever drop      *
49
 *  below zero.                                             *
50
 *                                                          *
51
 ************************************************************
52
 */
53
  if (!CaptureOrPromote(move)) {
54
    if (tree->killers[ply].move1 != move) {
55
      tree->killers[ply].move2 = tree->killers[ply].move1;
56
      tree->killers[ply].move1 = move;
57
    }
58
/*
59
 ************************************************************
60
 *                                                          *
61
 *  Set the counter-move for the move at the previous ply   *
62
 *  to be this move that caused the fail-high.              *
63
 *                                                          *
64
 ************************************************************
65
 */
154 pmbaty 66
    if (tree->counter_move[tree->curmv[ply - 1] & 4095].move1 != move) {
67
      tree->counter_move[tree->curmv[ply - 1] & 4095].move2 =
68
          tree->counter_move[tree->curmv[ply - 1] & 4095].move1;
69
      tree->counter_move[tree->curmv[ply - 1] & 4095].move1 = move;
108 pmbaty 70
    }
71
/*
72
 ************************************************************
73
 *                                                          *
74
 *  Set the move-pair for the move two plies back so that   *
75
 *  if we play that move again, we will follow up with this *
76
 *  move to continue the "plan".                            *
77
 *                                                          *
78
 ************************************************************
79
 */
80
    if (ply > 2) {
154 pmbaty 81
      if (tree->move_pair[tree->curmv[ply - 2] & 4095].move1 != move) {
82
        tree->move_pair[tree->curmv[ply - 2] & 4095].move2 =
83
            tree->move_pair[tree->curmv[ply - 2] & 4095].move1;
84
        tree->move_pair[tree->curmv[ply - 2] & 4095].move1 = move;
108 pmbaty 85
      }
86
    }
87
/*
88
 ************************************************************
89
 *                                                          *
90
 *  Adjust the history counter for the move that caused the *
154 pmbaty 91
 *  fail-high, limiting the max value to 2048.              *
108 pmbaty 92
 *                                                          *
93
 ************************************************************
94
 */
95
    if (depth > 5) {
96
      mindex = HistoryIndex(side, move);
97
      history[mindex] += (2048 - history[mindex]) >> 5;
98
/*
99
 ************************************************************
100
 *                                                          *
101
 *  Adjust the history counters for the moves that were     *
102
 *  searched but did not cause a fail-high, limiting the    *
154 pmbaty 103
 *  min value to 0.                                         *
108 pmbaty 104
 *                                                          *
105
 ************************************************************
106
 */
107
      for (i = 1; i <= searched[0]; i++) {
108
        index = HistoryIndex(side, searched[i]);
109
        if (index != mindex)
110
          history[index] -= history[index] >> 5;
111
      }
112
    }
113
  }
114
}