1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-04-30 08:43:09 +00:00

Better document how history works

Both with added comment and changing the API to
reflect that only destination square and moved piece
is important for history.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
Marco Costalba 2009-05-15 16:42:30 +02:00
parent 8df816f869
commit 436fa5c8fa
4 changed files with 50 additions and 44 deletions

View file

@ -32,14 +32,13 @@
//// Functions //// Functions
//// ////
/// Constructor /// Constructor
History::History() { History::History() { clear(); }
this->clear();
}
/// History::clear() clears the history tables. /// History::clear() clears the history tables
void History::clear() { void History::clear() {
memset(history, 0, 2 * 8 * 64 * sizeof(int)); memset(history, 0, 2 * 8 * 64 * sizeof(int));
@ -50,20 +49,21 @@ void History::clear() {
/// History::success() registers a move as being successful. This is done /// History::success() registers a move as being successful. This is done
/// whenever a non-capturing move causes a beta cutoff in the main search. /// whenever a non-capturing move causes a beta cutoff in the main search.
/// The three parameters are the moving piece, the move itself, and the /// The three parameters are the moving piece, the destination square, and
/// search depth. /// the search depth.
void History::success(Piece p, Square to, Depth d) {
void History::success(Piece p, Move m, Depth d) {
assert(piece_is_ok(p)); assert(piece_is_ok(p));
assert(move_is_ok(m)); assert(square_is_ok(to));
history[p][move_to(m)] += int(d) * int(d); history[p][to] += int(d) * int(d);
successCount[p][move_to(m)]++; successCount[p][to]++;
// Prevent history overflow: // Prevent history overflow
if(history[p][move_to(m)] >= HistoryMax) if (history[p][to] >= HistoryMax)
for(int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
for(int j = 0; j < 64; j++) for (int j = 0; j < 64; j++)
history[i][j] /= 2; history[i][j] /= 2;
} }
@ -72,31 +72,34 @@ void History::success(Piece p, Move m, Depth d) {
/// called for each non-capturing move which failed to produce a beta cutoff /// called for each non-capturing move which failed to produce a beta cutoff
/// at a node where a beta cutoff was finally found. /// at a node where a beta cutoff was finally found.
void History::failure(Piece p, Move m) { void History::failure(Piece p, Square to) {
assert(piece_is_ok(p));
assert(move_is_ok(m));
failureCount[p][move_to(m)]++; assert(piece_is_ok(p));
assert(square_is_ok(to));
failureCount[p][to]++;
} }
/// History::move_ordering_score() returns an integer value used to order the /// History::move_ordering_score() returns an integer value used to order the
/// non-capturing moves in the MovePicker class. /// non-capturing moves in the MovePicker class.
int History::move_ordering_score(Piece p, Move m) const { int History::move_ordering_score(Piece p, Square to) const {
assert(piece_is_ok(p));
assert(move_is_ok(m));
return history[p][move_to(m)]; assert(piece_is_ok(p));
assert(square_is_ok(to));
return history[p][to];
} }
/// History::ok_to_prune() decides whether a move has been sufficiently /// History::ok_to_prune() decides whether a move has been sufficiently
/// unsuccessful that it makes sense to prune it entirely. /// unsuccessful that it makes sense to prune it entirely.
bool History::ok_to_prune(Piece p, Move m, Depth d) const { bool History::ok_to_prune(Piece p, Square to, Depth d) const {
assert(piece_is_ok(p));
assert(move_is_ok(m));
return (int(d) * successCount[p][move_to(m)] < failureCount[p][move_to(m)]); assert(piece_is_ok(p));
assert(square_is_ok(to));
return (int(d) * successCount[p][to] < failureCount[p][to]);
} }

View file

@ -34,19 +34,22 @@
//// Types //// Types
//// ////
/// The History class stores statistics about how often different moves have /// The History class stores statistics about how often different moves
/// been successful or unsuccessful during the current search. These /// have been successful or unsuccessful during the current search. These
/// statistics are used for reduction and move ordering decisions. /// statistics are used for reduction and move ordering decisions. History
/// entries are stored according only to moving piece and destination square,
/// in particular two moves with different origin but same destination and
/// same piece will be considered identical.
class History { class History {
public: public:
History(); History();
void clear(); void clear();
void success(Piece p, Move m, Depth d); void success(Piece p, Square to, Depth d);
void failure(Piece p, Move m); void failure(Piece p, Square to);
int move_ordering_score(Piece p, Move m) const; int move_ordering_score(Piece p, Square to) const;
bool ok_to_prune(Piece p, Move m, Depth d) const; bool ok_to_prune(Piece p, Square to, Depth d) const;
private: private:
int history[16][64]; // [piece][square] int history[16][64]; // [piece][square]

View file

@ -264,7 +264,7 @@ void MovePicker::score_noncaptures() {
else if (m == killer2) else if (m == killer2)
hs = HistoryMax + 1; hs = HistoryMax + 1;
else else
hs = H.move_ordering_score(pos.piece_on(move_from(m)), m); hs = H.move_ordering_score(pos.piece_on(move_from(m)), move_to(m));
// Ensure history is always preferred to pst // Ensure history is always preferred to pst
if (hs > 0) if (hs > 0)
@ -287,7 +287,7 @@ void MovePicker::score_evasions() {
int seeScore = pos.see(m); int seeScore = pos.see(m);
moves[i].score = (seeScore >= 0)? seeScore + HistoryMax : seeScore; moves[i].score = (seeScore >= 0)? seeScore + HistoryMax : seeScore;
} else } else
moves[i].score = H.move_ordering_score(pos.piece_on(move_from(m)), m); moves[i].score = H.move_ordering_score(pos.piece_on(move_from(m)), move_to(m));
} }
} }

View file

@ -2332,7 +2332,7 @@ namespace {
return false; return false;
// Case 4: Don't prune moves with good history. // Case 4: Don't prune moves with good history.
if (!H.ok_to_prune(pos.piece_on(move_from(m)), m, d)) if (!H.ok_to_prune(pos.piece_on(mfrom), mto, d))
return false; return false;
// Case 5: If the moving piece in the threatened move is a slider, don't // Case 5: If the moving piece in the threatened move is a slider, don't
@ -2379,13 +2379,13 @@ namespace {
void update_history(const Position& pos, Move m, Depth depth, void update_history(const Position& pos, Move m, Depth depth,
Move movesSearched[], int moveCount) { Move movesSearched[], int moveCount) {
H.success(pos.piece_on(move_from(m)), m, depth); H.success(pos.piece_on(move_from(m)), move_to(m), depth);
for (int i = 0; i < moveCount - 1; i++) for (int i = 0; i < moveCount - 1; i++)
{ {
assert(m != movesSearched[i]); assert(m != movesSearched[i]);
if (ok_to_history(pos, movesSearched[i])) if (ok_to_history(pos, movesSearched[i]))
H.failure(pos.piece_on(move_from(movesSearched[i])), movesSearched[i]); H.failure(pos.piece_on(move_from(movesSearched[i])), move_to(movesSearched[i]));
} }
} }