Quote:
Originally Posted by silkytail
Любопытно было бы взглянуть на логику, если это как-либо обобщено, а не тупо захардкожена последовательность действий.
Я тут хочу замахнуться на что-то типа goal-oriented аи, но пока не очень ясно, как это можно сделать.
|
лично я рассматриваю бота как автомат. У автоматов есть та называемые устойчивые состояния. Ну в игре например это указатель текущего действия, насколько я понимаю.
у бота моего тоже есть флаг действия.
0-ничего не делаем
1-летим к waypoint
2-летим к выбранной цели (цель лубого плана: нпс, моб, рес, игрок итд)
3-активируем цель(убиваем моба, бафаем)
255-блокировка ЧС (черезвычайная ситуация- когда продолжать работу как обычно бот уже не может. Это грозит здоровью или еще чем нибудь. есть еще флаг причины блокировки, чтобы потом эту блокировку снять)
(эти устойчивые состояния добавятся, я так думаю)
Вся фишка в универсальности понятия цели- минимальная единица, частица общей Цели (пока бред, но я счас поясню)
К примеру, Цель- это сбор ресов. Тогда эта самая цель- или подцель - это самый близкий,выгодный, не занятый ресурс.
Если главная Цель это фарм, тогда подцели это мобы и лут.
ну и.т.д. и.т.п.
Эти подцели можно, при желании, выстраивать в цепочки, ставить в зависимость друг от друга, ставить им важность и тд.
Следующая фишка, это единая функция поиска следующей цели.
Она рассматривает варианты, фильтрует, высчитывает самую удачную цель, (например, моб встал отдельно от кучки мобов, значит его удобнее вытянуть, не сагрив всю ораву мобов на себя).
Если мы делаем квест, то она смотрит, сколько каких мобов еще надо замочить, куда лететь, какого нпс открыть итд. Одновременно, она проверяет актуальность текущей цели, выбранной ранее. Например, пока бежали к мобу, его занял другой игрок- цель более неактуальна-выбирается другая.
логика действий такова:
главный поток вызывает поиск цели, сохраняет ее указатель себе.
потом, в зависимости от текущего устойчивого состояния и значения найденной цели, ее типа и местоположения, он выбирает что сделать и в какое состояние переключиться.
Например, текущая цель не равна найденной цели, следовательно, либо текущая цель неактуальна, либо новая цель более выгодна. (бывает, например, летит к ресурсу какому нибудь- потом бац, прямо около перса респнулся новый ресурс- нужно забить на тот что далеко и собрать тот что под ногами) Действие очевидно- двигаться к новой цели, тк она более выгодна.
потом при следующем проходе потока, он смотрит: ага, я двигаюсь к цели такой то. Ага, расстояние до цели достаточно для ее активации (копнуть рес, ударить моба итд). Значит посылаем клиенту команду активировать, переключаем состояние в режим активации.
Следующий проход потока:
Ага, мы активируем цель. Сколько процентов готово (жизнь моба, процесс копания) Если уже все, то переключаем в режим 0 (ничего не делания)
В новой итерации, в самом начале мы ищем новую цель. И снова по кругу- полететь к цели, активировать.
Если цель не найдена, то летит к ближайшей точке маршрута, если такой есть. Попутно, разумеется ищем цель- если нашлась- го к ней
Потом летаем по маршруту по кругу, пока не найдется новая цель.
В случае ЧС ставится блокировка, потом например прыгаем на полет, поднимаемся повыше, ждем- это в случае с мобами или здоровьем/маной
С поломкой оружия/брони или переполнением инвентаря- ТП в город, или пешком/полетом. Там продаться/купить что нужно, отремонтироваться и го назад, к ближайшей точке маршрута/цели, если таковая есть.
В ситуации с нападением на бота другим игроком, можно продумать что делать- например свалить в город. или свалить в радиальном направлении и орать ему в ПМ типа "Ты че творишь?" итд.
В общем, блокировка - это способ обойти нестандартные ситуации.
После чего переводит состояние в режим 0.
Вот, я вроде описал задумку. весьма вкраце, правда)))
Здесь остается место для универсальности- это поиск цели, способ ее активации и блокировки в непредвиденных ситуациях. В принципе, я так думаю, этим алгоритмом можно описать практически любые варианты поведения. Другое дело, что это только основа- а частные случаи нужно сидеть и писать все равно. А чтобы бот стал по настоящему универсальным.. это надо сдохнуть похоже :-)
Кстати, трек, состоящий из waypoint-ов не обязательно делать кольцом.
думаю, его можно разветвить как угодно, главное заложить логику потом, как перескакивать с точки на точку.
ЗЫ, специально для origmas:
Потоки про которые я говорю, запускаются у меня, в моей программе(никуда не инжектятся).
Внутри тела простого потока, например, обновляющего списки объектов, стоит бесконечный цикл.
while Active do
begin
{Refresh here}
sleep(500);
end;
Ну поток следящий за движением к точке более сложный, но идея все та же.
поток выключается когда ставишь Active:= false.
Так он сам понимает, что пора выходить, сохраняет что нужно и делает Terminate.
Надеюсь, доступно объяснил)))