Я реализовал альфа-бета-поиск с таблицей транспонирования.
Есть ли у меня правильные идеи о хранении отсечек в таблице?
В частности, правильна ли моя схема возврата отсечений при попадании в таблицу? (И, соответственно, их сохранения.) Моя реализация, похоже, конфликтует с этот, но интуитивно он кажется мне правильным.
Кроме того, мой алгоритм никогда не сохраняет запись с флагом at_most. Когда мне следует сохранять эти записи?
Вот мой (упрощенный) код, демонстрирующий основные идеи:
int ab(board *b, int alpha, int beta, int ply) {
evaluation *stored = tt_get(b);
if (entryExists(stored) && stored->depth >= ply) {
if (stored->type == at_least) { // lower-bound
if (stored->score >= beta) return beta;
} else if (stored->type == at_most) { // upper bound
if (stored->score <= alpha) return alpha;
} else { // exact
if (stored->score >= beta) return beta; // respect fail-hard cutoff
if (stored->score < alpha) return alpha; // alpha cutoff
return stored->score;
}
}
if (ply == 0) return quiesce(b, alpha, beta, ply);
int num_children = 0;
move chosen_move = no_move;
move *moves = board_moves(b, &num_children);
int localbest = NEG_INFINITY;
for (int i = 0; i < num_children; i++) {
apply(b, moves[i]);
int score = -ab(b, -beta, -alpha, ply - 1);
unapply(b, moves[i]);
if (score >= beta) {
tt_put(b, (evaluation){moves[i], score, at_least, ply});
return beta; // fail-hard
}
if (score >= localbest) {
localbest = score;
chosen_move = moves[i];
if (score > alpha) alpha = score;
}
}
tt_put(b, (evaluation){chosen_move, alpha, exact, ply});
return alpha;
}