#include "chess.h" #include "data.h" /* last modified 08/15/15 */ /* ******************************************************************************* * * * History() is used to maintain the two killer moves for each ply. The * * most recently used killer is always first in the list. * * * * History() also maintains two counter-moves. These are moves that are * * directly used to refute a specific move at the previous ply, rather than * * just a plain killer that has caused cutoffs previously. * * * * History() finally remembers two moves that were played after a specific * * move at ply-2 (ie the two moves together create some sort of "plan".) * * * * History() also maintains the history counters. Each time a move fails * * high, it's history count is increased, while all other moves that were * * searched will have their counts reduced. The current counter is a * * saturating counter in the range 0 <= N <= 2047. * * * ******************************************************************************* */ void History(TREE * RESTRICT tree, int ply, int depth, int side, int move, int searched[]) { int i, index, mindex; /* ************************************************************ * * * Now, add this move to the current killer moves if it is * * not already there. If the move is already first in the * * list, leave it there, otherwise move the first one down * * to slot two and insert this move into slot one. * * * * If the best move so far is a capture or a promotion, * * we skip updating the killers (but still update history * * information) since we search good captures first, which * * happens before killers are tried, making capture moves * * useless here. * * * * The update value does not depend on depth. I used a * * function of depth for years, but as I examined more and * * more trees, that seemed to be lacking because it gives * * a really large bias towards moves that work near the * * root, while most of the nodes searched are near the * * tips. One unusual characteristic of this counter is * * that it is a software-based saturating counter. That * * is, it can never exceed 2047, nor can it ever drop * * below zero. * * * ************************************************************ */ if (!CaptureOrPromote(move)) { if (tree->killers[ply].move1 != move) { tree->killers[ply].move2 = tree->killers[ply].move1; tree->killers[ply].move1 = move; } /* ************************************************************ * * * Set the counter-move for the move at the previous ply * * to be this move that caused the fail-high. * * * ************************************************************ */ if (tree->counter_move[tree->curmv[ply - 1] & 4095].move1 != move) { tree->counter_move[tree->curmv[ply - 1] & 4095].move2 = tree->counter_move[tree->curmv[ply - 1] & 4095].move1; tree->counter_move[tree->curmv[ply - 1] & 4095].move1 = move; } /* ************************************************************ * * * Set the move-pair for the move two plies back so that * * if we play that move again, we will follow up with this * * move to continue the "plan". * * * ************************************************************ */ if (ply > 2) { if (tree->move_pair[tree->curmv[ply - 2] & 4095].move1 != move) { tree->move_pair[tree->curmv[ply - 2] & 4095].move2 = tree->move_pair[tree->curmv[ply - 2] & 4095].move1; tree->move_pair[tree->curmv[ply - 2] & 4095].move1 = move; } } /* ************************************************************ * * * Adjust the history counter for the move that caused the * * fail-high, limiting the max value to 2048. * * * ************************************************************ */ if (depth > 5) { mindex = HistoryIndex(side, move); history[mindex] += (2048 - history[mindex]) >> 5; /* ************************************************************ * * * Adjust the history counters for the moves that were * * searched but did not cause a fail-high, limiting the * * min value to 0. * * * ************************************************************ */ for (i = 1; i <= searched[0]; i++) { index = HistoryIndex(side, searched[i]); if (index != mindex) history[index] -= history[index] >> 5; } } } }