Супер-краткий гайд (всё описанное ниже сугубо моё виденье) по симуляционным деревьям и игровым ботам для них:
1) Определяется базовый класс бота с главным методом getAnswer()
2) От него наследуется в зависимости от сложности игры симуляционный бот и боты соперники (если соперники не являются умными, а допустим какими-то мобами, то можно не делать такое наследование, а просто, в зависимости от сложности их алгоритмов их описать, прибегнув к реверсу или исследованию поведения этих игровых объектов). Это всё нужно для того, чтобы упростить симуляцию, потому что полная симуляцию и за себя и за соперников обычно дорогая, но если мощности позволяют - то можно симулировать и соперников
3) Далее, пишется сама симуляция (пока что полный каркас), если игра пошаговая, то всё просто - нам нужно рассмотреть просто все основные состояния игры и их записать, чем буде более полная картина, тем меньше будет тупняков у бота и зависаний - далее, если мы в теории полное дерево имеем, то мы в терминальных узлах однозначно понимаем в какой ситуации выиграли, по этому по минимаксу можем протягивать лучшие значение. Если игра не пошаговая, то у нас будет приближённая симуляция с разными стейтами через какие-то моменты времени, в узлы мы опять же кидаем копии состояния игры (под этим подразумеваю нужные нам для принятия решений данные).
4) Однако в большинстве игр мы не можем полную симуляцию сделать, по этому мы начинаем делать обрезания дерева, альфа-бета отсечение, а также втыкание каких-то свои эвристик в терминальные узлы дерева, по которым мы оцениваем уже состояние игры
5) Какие-то ситуации мы можем считать эквивалентными и их не симулировать, я это назову кластеризациями, хотя это не обязательно именно они. Например, если у нас несколько юнитов, а это пошаговая игра и мы хотим просимулировать их действия, нам не обязательно за каждого эти действия просимулировать, мы можем симулировать сразу конечные состояния - это тоже укарачивает дерево
6) Создаём несколько разных эвристик и сравниваем их по качеству