Расчет выходной мощности двух армий

20

Я программирую стратегическую игру, используя Flash. Игра работает очень похоже на знаменитую игру «Травиан».

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

Как я могу выразить это влияние этих различий в уравнении боя?

Кажется, это легко, если они имеют только точки att и def, но когда дело доходит до зависимости типа модулей, я теряюсь.

Али Албахрани
источник
6
Должен ли исход ваших сражений быть чисто детерминированным или вы хотите использовать какую-то случайность?
sum1stolemyname
4
Я не думаю, что это должно быть помечено как многопользовательская игра, так как это не дано ОП - это может быть человек против ИИ. И под «типовой зависимостью» мы говорим о классической вещи типа рок-> ножницы-> бумага-> рок?
Коммунистическая утка

Ответы:

10

В дополнение к поддержке предложения Амита о рассмотрении уравнений Ланчестера, я просто хочу добавить, что это решение по разработке игры, а не эмпирический факт, который мы можем вам дать. Если вы хотите принять во внимание тип юнита, вы должны решить, что это значит. Это означает выбор уравнения, которое включает в себя все факторы, которые вы хотите, чтобы ваш игровой процесс включал. Если вы хотите, чтобы пехота была лучше, чем кавалерия, то вам нужно решить, что это должно означать, например. сколько кавалерии нужно, чтобы равняться 100 пехоте? И имеет ли значение кто на кого нападает? Вы, похоже, намекаете, что просто дать пехоте и кавалерии разные значения атаки и защиты недостаточно, почему это так? Что еще вы пытаетесь представить, что не может быть охвачено только этими ценностями?

Вы должны решить, какие факторы вы хотите смоделировать в своей игре, поскольку они влияют на то, как игроки будут к ней подходить. Они могут включать размер / количество единиц, тип единицы, опыт единицы (например, статус ветерана), влияние местности и окружающей среды, различия между атакующими и обороняющимися, если таковые имеются, моделировать ли урон и истощение или нет, моделировать ли время в течение битва, способность уйти или убежать (возможно, включая моделирование морали), сколько случайности вы хотите в уравнении, и так далее.

Как только вы все это знаете, вы можете использовать несколько основных математических подходов. Вы можете сделать систему «шанс поразить» раунд за раундом, как во многих RPG, например. боевая система d20. Вы могли бы сделать взвешенную систему бросков монет «атака против защиты», как в оригинальной игре Civilization. Вы можете заставить каждую сторону генерировать счет, добавляя атрибуты к случайному числу, и тот, кто получает наибольшее значение, выигрывает. И вы можете переставлять эти системы, чтобы работать по принципу «круг за туром», или вычитать очки жизни, очки морали или что-то еще. Любая система может работать, но вы должны сбалансировать ее так, как хотите. В конечном счете, выбор способа моделирования боя является ключевой частью игрового дизайна, и это не то, что другие люди могут просто дать вам.

Kylotan
источник
Вы совершенно правы, Килотан. У меня были некоторые идеи по поводу боя до начала разработки игры. Тем не менее, я опубликовал этот вопрос, спрашивая, есть ли лучший способ разработать его и выяснить, как лучше всего реализовать его. Я выиграл с обеих целей, я думаю :) Мой друг, не могли бы вы сказать мне, где я могу найти больше информации об этих математических подходах? Кроме того, если я отвечу на все вопросы, которые вы задаете о выборе системы, можете ли вы мне посоветовать, какая из них лучше всего подходит для моего случая? Большое спасибо за ваше время :)
Али Албахрани
Я не могу сказать вам, что будет лучше, но вы, вероятно, должны начать с простого и улучшить это, если вам нужно. Травиан, кажется, имеет простую систему атаки против защиты, с 2 типами юнитов (пехота и кавалерия) и 2 показателями защиты на юнита соответственно. Простой способ разрешить битву, используемый в Civilization 1, состоит в том, чтобы разделить показатель атаки атакующего на общую сумму плюс показатель защиты защитника. Это дает вам процент. Теперь выберите случайное число от 0 до 100 процентов. Если он ниже, чем показатель атаки атакующего, атакующие побеждают. В противном случае защитники побеждают.
Kylotan
15

Для Solar Realms Elite меня вдохновили уравнения Ланчестера для моделирования войны . У меня было несколько одновременных боев в каждом раунде битвы.

В первом бою все напали на солдат. В SRE солдаты лучше против солдат (это не каменные ножницы, а пехота, воздушная атака и дальний космос). Я установил силу атаки и защиты, где солдаты лучше всех атаковали:

attack_strength = 3*soldiers + 1*fighters + 2*cruisers
defense_strength = 10*soldiers

Во втором бою все атаковали оборонительные посты. В SRE истребители (воздушные) лучше всего противостоят станциям обороны (например, зенитным):

attack_strength = 1*soldiers + 4*fighters + 2*cruisers
defense_strength = 25*defense_stations

В третьем бою все атаковали тяжелые крейсеры. В SRE тяжелые крейсеры находятся в космосе и лучше других против тяжелых крейсеров:

attack_strength = 1*soldiers + 1*fighters + 10*cruisers
defense_strength = 15*cruisers

(Я не помню, какие константы я использовал; это всего лишь примеры.) В каждом раунде битвы атакующие теряют некоторую часть силы защиты, а защитники теряют некоторую часть силы атаки. Я считаю, что это соответствует закону квадрата Ланчестера ( здесь уравнения ). Я добавил случайность, но я точно не помню, где. После каждого раунда битвы армии становились меньше. Я ставлю максимальный лимит на количество раундов; после этого проигравшая сторона отступит.

Нелегко было размещать пехоту на земле, прокладывая путь в дальний космос, но по причинам геймплея она работала лучше, когда все юниты могли сражаться со всеми остальными юнитами (при сниженной эффективности).

amitp
источник
12

Я склонен говорить: «Если вы не можете найти явное решение, ищите неявное». Вы можете смоделировать битву внутри, пока одна армия не будет уничтожена или не отступит (в зависимости от возможных результатов вашей игры).

Я бы использовал что-то вроде этого:

На каждой итерации битвы все юниты являются оппортунистическими, поэтому они стараются нанести как можно больше урона. Каждый юнит выбирает вражеского юнита, которого он собирается атаковать в этом раунде, основываясь на известных достоинствах / недостатках.

Затем все субфайты выполняются. Пример:

Пусть копейщики эффективны против кавалерии, кавалерия эффективна против лучников и лучники эффективны против копейщиков.

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

Каждое событие юнит-атаки-юнит решается отдельно, при этом проигравший юнит поврежден или помечен как уничтоженный.

После того, как все отдельные бои будут решены, удалите все юниты, которые были критически повреждены или уничтожены.

Следующая итерация начинается с использования уменьшенных армий.

sum1stolemyname
источник
Действительно согласен с этим постом. Лучше перебирать битву, чем сводить ее к одному уравнению. И я бы определенно добавил к этому немного случайности. Должен быть такой очень маленький шанс, что слабый защитник бросит высоко и получит критический удар. Еще одним преимуществом итеративного является то, что вы можете создать повествование о событиях, чтобы показать игроку. «Мечники напали и вскоре уничтожили лакеев, но затем на Голгофу прибыли и…»
Тим Холт
Мне очень нравится ваш ответ, и я думаю, что я буду реализовывать его со случайностью :)
Али Албахрани
3

Я бета-тестирую игру, которая в настоящее время представляет собой простую версию Solar Realms ( Star Empire Elite ), и я начал с использования чего-то похожего на уравнения Амит (см. Выше). В частности, мне понравилась идея иметь три этапа в битве, где вам нужно было выиграть два из трех. Но я также хотел внести элемент случайности в битву, и для этого на меня повлияли некоторые настольные игры.

Обработка является проблемой, если игра должна масштабироваться, поэтому я не хотел следовать методу, предложенному sum1stolemyname выше, хотя, если ваша игра использует клиент для обработки результатов, в отличие от сервера, это кажется хороший подход.

Я решил разбить битву на две фазы (аналогичные трем в модели Амита): воздух и земля. Я рассчитываю силу атаки и защиты и корректирую силу атаки на долю (чтобы дать преимущество защитнику). В этот момент, если сила атаки и сила защиты равны, атака имеет 50% шанс на победу. Оттуда я настраиваю процентный шанс на победу вверх или вниз в зависимости от того, насколько больше (или меньше) силы у атакующего по сравнению с защитником. Вот некоторые упрощенные уравнения для воздуха:

air_attack_strength = 1 * soldiers + 10 * fighters
air_defence_strength = 2 * soldiers + 25 * stations

differential = (air_attack_strength - air_defence_strength) * constant

chance_of_victory = 50 - differential

Я указываю, что chance_of_victory никогда не может быть больше 80 или меньше 5. Оттуда я просто генерирую случайное число из 100, а затем переношу этот результат в битву за землю.

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

Роберт Йогурт
источник