|
||
Для сглаживания эффекта горизонта взятия считаем до конца. Для этого по достижении предельной глубины полного поиска вызываем форсировку, в которой обсчитываем только взятия. Здесь я не использую детектор шахов, поэтому возникают ситуации, когда бьют короля и мы должны их обрабатывать. Тут две ключевые темы - завышение альфы статической оценкой и сортировка методом mvv/lva. Опишу алгоритм за белых. Так это сделано в Ифрите (Ifrit_b2_6): Forced_variant_white { Считаем статическую оценку позиции. В ней мы обсчитываем только материал. value_max = Eval_forced; Пытаемся получить отсечку по бете. if(value_max >= beta) return value_max; Генерируем и сортируем ходы. Generator_captures_white; Sorting_captures_moves; Если список взятий пустой, то возвращаемся со статической оценкой. if (0 == list_surplus_moves.end_list) return value_max; Статической оценкой пытаемся завысить альфу. if(value_max >= alpha){ alpha = value_max; } Обсчитываем список взятий. for (int i=0; i < list_surplus_moves.end_list; i++){ Делаем ход. Onward_moves_white; Обрабатываем случай взятого короля. if (( list_surplus_moves.move[i] & 63) != 6){ Если король еще живой то, вызываем рекурсивно перебор за черных. value = Forced_variant_black(depth + 1); Откатываем ход. Backs_moves_white; Ищем максимум. if (value > value_max) value_max = value; Пытаемся улучшить альфу и при случае отсечь по бете. if (value > alpha){ alpha = value; if(alpha >= beta) return alpha; } }else{ Если же короля побили, то, значит, был шах или мат и дальше считать смысла нет. Отнимаем глубину, что бы выбирал кратчайший путь. value = (1000000 – depth * 1000); Откатываем ход. Backs_moves_white; return value; } } return value_max; } За черных без комментариев. Forced_variant_black { value_min = Eval_forced(bitboard); if(value_min <= alpha) return value_min; Generator_captures_black; Sorting_captures_moves; if (0 == list_surplus_moves.end_list) return value_min; if(value_min <= beta) beta = value_min; for (int i=0; I < list_surplus_moves.end_list; i++){ Onward_moves_black; if (( list_surplus_moves.move[i] & 63) != 6){ value=Forced_variant_white(depth + 1); Backs_moves_black; if (value < value_min)value_min = value; if (value < beta){ beta = value; if(alpha >= beta) return beta; } }else{ value = -(1000000 – depth * 1000); Backs_moves_black; return value; } } return value_min; } Посмотрим, насколько форсировка тормозит полный перебор. Кстати, это полный настоящий перебор без а-б :) Без форсажа. 5/5 00:05 4.865.609 1 +1,19 e2e4 e7e5 Ng1f3 Bf8e7 Nf3xe5 6/6 02:05 119.060.324 1 -0,82 e2e4 b7b6 d2d4 Bc8b7 e4e5 Bb7xg2 С форсажем. 5/5 00:10 4.865.609 506.462 +0,26 e2e4 Ng8f6 e4e5 Nf6e4 d2d4 6/6 05:14 119.060.324 407.828 +0,12 e2e4 Ng8f6 Nb1c3 d7d5 e4xd5 Nf6xd5 |