Я реализую шахматный движок, и я написал довольно сложную процедуру поиска альфа-бета с таблицами поиска и транспонирования покоя. Тем не менее, я наблюдаю странную ошибку.
Функция оценки использует кусочно-квадратные таблицы, например, для пешек:
static int ptable_pawn[64] = {
0, 0, 0, 0, 0, 0, 0, 0,
30, 35, 35, 40, 40, 35, 35, 30,
20, 25, 25, 30, 30, 25, 25, 20,
10, 20, 20, 20, 20, 20, 20, 10,
3, 0, 14, 15, 15, 14, 0, 3,
0, 5, 3, 10, 10, 3, 5, 0,
5, 5, 5, 5, 5, 5, 5, 5,
0, 0, 0, 0, 0, 0, 0, 0
};
При черном повороте таблица отражается по оси x. В частности, если вам интересно, поиск происходит таким образом, когда столбцы A-H отображаются в 0-7, а строки - 0-7 с белой стороны:
int ptable_index_for_white(int col, int row) {
return col+56-(row*8);
}
int ptable_index_for_black(int col, int row) {
return col+(row*8);
}
Таким образом, пешка на h4 (координаты 7, 3) стоит 3 очка (сантипаны) для белого, а пешка на f6 (координата 5, 5) стоит 3 сантипа за черную.
Вся оценочная функция в настоящее время представляет собой кусочно-квадратные таблицы и материал.
При большей глубине поиска мой движок выбирает некоторые действительно ужасные ходы. Рассмотрим этот выход, созданный в исходной позиции:
Iterative Deepening Analysis Results (including cached analysis)
Searching at depth 1... d1 [+0.10]: 1.b1c3
(4 new nodes, 39 new qnodes, 0 qnode aborts, 0ms), 162kN/s
Searching at depth 2... d2 [+0.00]: 1.e2e4 d7d5
(34 new nodes, 78 new qnodes, 0 qnode aborts, 1ms), 135kN/s
Searching at depth 3... d3 [+0.30]: 1.d2d4 d7d5 2.c1f4
(179 new nodes, 1310 new qnodes, 0 qnode aborts, 4ms), 337kN/s
Searching at depth 4... d4 [+0.00]: 1.g1f3 b8c6 2.e2e4 d7d5
(728 new nodes, 2222 new qnodes, 0 qnode aborts, 14ms), 213kN/s
Searching at depth 5... d5 [+0.20]: 1.b1a3 g8f6 2.d2d4 h8g8 3.c1f4
(3508 new nodes, 27635 new qnodes, 0 qnode aborts, 103ms), 302kN/s
Searching at depth 6... d6 [-0.08]: 1.d2d4 a7a5 2.c1f4 b7b6 3.f4c1 c8b7
(21033 new nodes, 112915 new qnodes, 0 qnode aborts, 654ms), 205kN/s
Searching at depth 7... d7 [+0.20]: 1.b1a3 g8f6 2.a1b1 h8g8 3.d2d4 g8h8 4.c1f4
(39763 new nodes, 330837 new qnodes, 0 qnode aborts, 1438ms), 258kN/s
Searching at depth 8... d8 [-0.05]: 1.e2e4 a7a6 2.e4e5 a6a5 3.h2h4 d7d6 4.e5d6 c7d6
(251338 new nodes, 2054526 new qnodes, 0 qnode aborts, 12098ms), 191kN/s
На глубине 8 обратите внимание, что черный цвет открывается с помощью движений "... a7a6... a6a5", которые ужасны в соответствии с квадратом квадрата. Кроме того, "h2h4" - это ужасное движение для белого. Почему моя функция поиска выбирает такие причудливые ходы? Примечательно, что это происходит только на больших глубинах (движения на глубине 3 выглядят отлично).
Кроме того, поиск часто прогоняет куски! Рассмотрим следующую позицию:
Двигатель рекомендует ужасную ошибку (3... f5h3), как-то пропуская очевидный ответ (4. g2h3):
Searching at depth 7... d7 [+0.17]: 3...f5h3 4.e3e4 h3g4 5.f2f3 g8f6 6.e4d5 f6d5
(156240 new nodes, 3473795 new qnodes, 0 qnode aborts, 17715ms), 205kN/s
Поиск покоя не задействован, так как ошибка происходит при слое 1 (!!).
Вот код для моих функций поиска. Мне жаль, что это так долго: я упростил, насколько мог, но не могу понять, какие части не имеют отношения к ошибке. Я предполагаю, что мой алгоритм как-то тонко ошибочен.
Я вызываю поиск следующим образом:
int result = abq(b, NEG_INFINITY, POS_INFINITY, ply);