Я решил написать небольшую программу, которая решает TicTacToe, чтобы испытать эффект некоторых методов обрезки на тривиальной игре. Полное игровое дерево, использующее минимакс для его решения, заканчивается только 549 946 возможными играми. При обрезке альфа-бета количество состояний, необходимых для оценки, было уменьшено до 18 297. Затем я применил таблицу транспозиций, которая приносит номер до 2 592. Теперь я хочу посмотреть, как мало это число.
Следующее усовершенствование, которое я хочу применить, - это стратегическое сокращение. Основная идея заключается в объединении состояний, имеющих эквивалентное стратегическое значение. Например, на первом ходу, если X играет сначала, нет ничего стратегически иного (если предположить, что ваш оппонент играет оптимально) о выборе одного угла вместо другого. В той же ситуации то же самое относится к центру стен доски, а центр также значителен. Если вы уменьшите только до значительных состояний, вы получите только 3 состояния для оценки на первом ходу вместо 9. Этот метод должен быть очень полезным, поскольку он обрезает состояния вблизи вершины игрового дерева. Эта идея исходила из метода GameShrink, созданного группой в CMU, только я стараюсь не писать общую форму и просто делать то, что необходимо для применения техники к TicTacToe.
Чтобы добиться этого, я изменил свою хэш-функцию (для таблицы транспозиции), чтобы перечислить все стратегически эквивалентные позиции (используя функции вращения и переворота) и вернуть только самое низкое значение для каждой платы. К сожалению, теперь моя программа думает, что X может заставить выиграть в 5 шагах от пустой доски, когда идет первым. После долгого отладочного сеанса мне показалось, что программа всегда возвращала ход для наименьшего стратегически значимого перемещения (я сохраняю последний ход в таблице транспозиций как часть моего состояния). Есть ли лучший способ добавить эту функцию или простой метод определения правильного перемещения, применимого к текущей ситуации, с тем, что я уже сделал?