Войти
ПрограммированиеФорумИгровая логика и ИИ

Бой армий под управлением ИИ (решено)

#0
21:22, 24 мар. 2020

Что - то никак не соображу как сделать.
Есть РТС в которой ИИ может воевать друг против друга. На глобальной карте есть армии у которой есть определенный набор параметров, такие как например численность. Битва выглядит просто как снижение параметров армии - проигравший тот у кого они кончились раньше. В общем, самое близкое это нечто схожее с серией Тотал Вар. Такие же армии на глобальной карте и так же они могут воевать друг с другом.
Так вот собственно вопрос. Как бы сделать так что бы объективно определять победителя?

Ну вот скажем одна армия состоит из десяти орков 80 лвл - 7 бойцов ближнего боя и 3 бойца дальнего боя, а другая из десяти дворфов 80 лвл ближнего боя. Мощь армии орков = 200, а армии дворфов = 140. Начинается битва, считаем эти параметры, по окончании орков побеждают и у них в остатке должно быть какое то количество бойцов. Вот что-то ни как не соображу как бы так сделать. Есть какие у кого мысли?


#1
(Правка: 23:04) 22:42, 24 мар. 2020

sledo
> по окончании орков побеждают
По тем данным которые представлены, не вдаваясь в особенности каждого персонажа, вполне законна ничья

Ну, а по выстраиванию логики расчета, должны быть "чистые данные" на основе которых должен производиться расчет. То есть непосредственно те параметры с помощью которых считается результат.

Допустим что все считается на основе здоровья и повреждения.
Пересчитываем орков 80+ бойцов дальнего боя и гномов например так
орки dps 7*10+3*20 = 130
орки hp 7*20+3*10 = 170
гномы dps 10*10 = 100
гномы hp 10*20 = 200

далее ищем "общий множитель" или плюсуем раунды пока у кого-то не закончиться жизнь.
орки 170 гномы 200
орки 70 гномы 70
орки -30 гномы -60

Получили три итерации. Сравниваем результаты и получаем что орки выиграли.
Можно просто посмотреть коэффициент отношения жизни к повреждению:
орки 170/100 = 1.7
гномы 200/130 = 1.5

И понять кто выиграл. Но кто из них остался в живых это вопрос другой.

Можно усложнить расчет тем что на каждом раунде будут пересчитываться "сырые данные" из оставшихся в живых. Для этого надо расставить приоритеты по урону. Наибольший приоритет у бойцов ближнего боя. Значит 70 это 3 бойца дальнего боя и 2 ближнего. У гномов остается 3 с половиной землекопа.
После первого раунда имеем:
орки dps 2*10+3*20 = 80
орки hp 2*20+3*10 = 70
гномы dps 3.5*10 = 35
гномы hp 3.5*20 = 70

орки 70 гномы 70
орки 35 гномы -10

Дальше нужно избавиться от минусов. -10 это наполовину мертвый гном, который ударил как полностью здоровый. То есть
10/20(hp)*10(dps) = 5
5 жизней у орков были отняты зря. Но картины это в целом не меняет.
Имеем 3 лучника и раненного орка.

#2
23:05, 24 мар. 2020

sledo
> Есть какие у кого мысли?
Думаю, стоит начать сначала. Всех уже достали эти "геймдизайнерские шаблоны".

ИзображениеТЕМА #26Изображение
Особенно #7. П.Н.Ткаченко и др. Математические модели боевых действий.- М.: "Советское радио". 1969.

#3
23:35, 24 мар. 2020

foxes
В целом мысль ясна, но немного не подходит для текущей задачи. Да, данных маловато, поскольку я сам еще не знаю что нужно, думал Тотал Вар такая игра которую каждый хоть раз видел)
Если будут в один момент биться скажем 100 армий по 200 тушек, то пересчет каждого бойца посадит комп в глубокий нокаут. Об этом я уже думал, поэтому формирование данных происходит в моменте создания самой армии.

Я придумал следующее: каждый боец и его экипировка имеет очки мощи. При формировании армии эти очки мощи складываются давая общую мощь армии. При событии "Битва" эти очки мощи сравниваются и побеждает тот кто имеет мощи больше. Потери же, формируются исходя из соотношения мощи сражающихся армий. Если армия орков имеет очков мощи 90, а армия дворфов имеет очков мощи 30, то орки потеряют треть своих бойцов. Случайно выбираем номер ячейки массива бойца которому не повезло и так пока их не будет треть от общего числа. Дворфы вымирают начисто.
Если очки мощи равны, то либо случайный победитель остается с одним бойцом, либо они взаимно уничтожают друг друга.

Вобщем вот такая формула:
количество_потерь = количество_бойцов_армии / (очки_мощи_орки / очки_мощи_дворфы)

Итого две строчки кода. Теперь вопрос, как экономно растянуть это по времени?)

#4
23:37, 24 мар. 2020

gudleifr
> Особенно #7. П.Н.Ткаченко и др. Математические модели боевых действий.- М.:
> "Советское радио". 1969.
Хм, очень любопытная штука. Благодарю!

#5
23:41, 24 мар. 2020

sledo
> Если будут в один момент биться скажем 100 армий по 200 тушек, то пересчет
> каждого бойца посадит комп в глубокий нокаут.
Ты умножение через сложение решил реализовывать?

#6
0:38, 25 мар. 2020

foxes
> Ты умножение через сложение решил реализовывать?
Ну так по факту каждый боец уникален, как их умножать в общем? Я же Тотал Вар в качестве наглядного примера не просто так привел - там армия состоит из отрядов, каждый отряд имеет кучу своих параметров которые меняются со временем. Полоски ХП у них нет - ее заменяет численность отряда. Тоже самое у меня, только армия из бойцов, а не отрядов, бойцы имеют свои характеристики. Так что да, в моем случае так или иначе придется каждого бойца считать.


В общем, чтобы не было недопонимания как выглядит жизнь армии.
Есть полководец, который имеет в подчинении солдат. Этот полководец имеет набор своих полководческих характеристик. Как он родился, то смотрит на свою армию и если у него недобор, идет по городам набирать бойцов в соответствии со своими характеристиками. Бойцы имеют свои характеристики, плюс имеют экипировку и оружие. Экипировка имеет свои параметры, оружие тоже. В дальнейшем еще техника будет. И вот все это хозяйство с иерархией характеристик должно воевать на глобальной карте с такой же армией противника. А этих армий может быть много- потому и глобальная карта. Скажем те же сто армий. Если армия полководца выжила, значит он опять идет добирать бойцов и снова в бой. И так до тех пор пока не сдохнет.
Сам же бой должен проходить не моментально, а с течением времени, для того чтобы другие полководцы могли например прийти на помощь. И вообще это странно если бой на 1000 тушек пройдет моментально. Соответственно по логике, чем больше в битве участвует бойцов, тем дольше длится бой.

В этом то и был затык - как учитывать все эти характеристики для определения победителя и чтобы это было просто, и правдоподобно.

В идеале было бы если за одну секунду, из армий выбывало бы Х количества бойцов и проигравший тот, у кого это количество закончилось бы первым.

#7
(Правка: 0:59) 0:57, 25 мар. 2020

sledo
> Сам же бой должен проходить не моментально, а с течением времени, для того
> чтобы другие полководцы могли например прийти на помощь. И вообще это странно
> если бой на 1000 тушек пройдет моментально. Соответственно по логике, чем
> больше в битве участвует бойцов, тем дольше длится бой.
Все таки непонятно что ты хочешь моделировать как персонажи бьют друг друга или просто посчитать бой. В любом случае даже аддитивный метод разных характеристик решается ну хотя бы на GPU. Даже CPU прекрасно справляется со сложением значений массива 1000x1000, меньше чем за секунду это точно.

#8
1:07, 25 мар. 2020

foxes
Просто посчитать бой, с учетом персонажей которые находятся в группе, и с учетом вещей которые находятся на персонаже.
Понятно что все это быстро в локальном смысле, но это не игра одной битвы, там много чего еще есть на что требуются мощности.

А что если и в самом деле сделать сложную симуляцию, а обсчет засунуть сопроцессор? Вот и зависимость от времени)

#9
1:32, 25 мар. 2020

Не по теме.
Gudleifr, не могли мы пересекаться на просторах Forth форума?

#10
8:15, 25 мар. 2020

flint2
Могли. Конечно, в Сети у меня есть пара тезок, но фортер из них я один.

#11
(Правка: 9:09) 8:59, 25 мар. 2020

Gudleifr, я к тому, что приятно лицезреть "старую гвардию", которая начинала, когда компьютеры ещё были большими.
Одна самокритика чего стоит.

#12
15:22, 25 мар. 2020

Все, решил этот вопрос.

В общем все сделал через классическую схему с ХП.
Очки мощи армии это демаг который армия наносит противнику. Количество войск - это ХП армии. Когда армии встречаются, то они завязывают бой и наносят один раз в секунду друг другу урон. Далее смотрим количество войск в начале итерации и количество войск в конце итерации, и удаляем разницу в цикле по случайно выбранным солдат из списка армии. У кого быстрее кончились солдаты, тот и проиграл сражение.

Просто и лаконично.

#13
19:04, 25 мар. 2020

sledo
> Просто и лаконично.
Это и есть Ланчестер. Во-первых, его можно сделать без итераций, а, во-вторых, поиграть с целераспределением.

ПрограммированиеФорумИгровая логика и ИИ