Заклинання заклинання - як оптимізувати шкоду за секунду


23

Уявіть, у нас є майстер, який знає кілька заклинань. Кожне заклинання має 3 атрибути: Пошкодження, час охолодження та час відкидання. Досить стандартні речі RPG.

Час виходу з ладу: кількість часу (t), яке пройде, перш ніж ви зможете передати це заклинання знову. Заклинання продовжується "охолодження" в той момент, коли воно починає кидати.

Час закидання: кількість часу (t), необхідного для використання заклинання. Хоча майстер кидає щось інше заклинання, неможливо подати, і його не можна скасувати.

Питання полягає в тому, як би ви максимізували шкоду з-за різних наборів заклинань?

Неважко підрахувати найвищий збиток за час лиття. Але як бути в ситуаціях, коли краще зачекати, щоб потім «застрягнути», наклавши заклинання з низькою шкодою, коли доступний набагато вищий?

Наприклад,

  1. Вогнена куля: 3000 пошкоджень, 3 секунди часу відкидання, 6 секунд охолодження.

  2. Frostbolt: 20 пошкоджень, 4 секунди час відливу, 4 секунди охолодження.

  3. Дробовик: 3 пошкодження, 3 секунди часу лиття, 3 секунди охолодження.

У цьому випадку ваш збиток на секунду більший, якщо ви вирішили перейти на нижнє заклинання DPCT (fireblast) замість морозу. Тому ми повинні враховувати наслідки вибору заклинання. alt текст

У наступному прикладі наводяться випадки "над кастингом" та "очікування". alt текст


Чому я б робив 1-3-1 у цій ситуації? Чому б не 1-2-1? Чому б не 1-2-3-1, що є більш ефективним, ніж 1-3-1-X, якщо 1-3-1 поодинці не вб'є ціль?

@Joe Wreschnig: Дякую, що вказав на це. Була помилка в моєму прикладі. Тепер це спрощено лише до 2 випадків.
— aaronfarr

1
Жадібний, як і у виборі найвищого доступного заклинання до dps, коли це можливо. Нехтування іншою логікою, тобто. чекання.
— aaronfarr

1
Тільки щоб каламутити воду. Розглянемо заклинання, яке завдає ∞ шкоди, але для того, щоб закинути, потрібно 50 секунд. Це dps / dpct є ∞, але його ніколи не слід вибирати, якщо мета може бути вбита іншими засобами менш ніж за 50 секунд.
— deft_code

1
Ви маєте посилання на дуп на math.stackexchange.com/questions/10414/…
— Sparr

Відповіді:


23

Все AI - пошук!

Коли ти потрапляєш у кишки ШІ, дивуєшся, наскільки це справді пошук .

  • стан : решта закриття всіх доступних заклинань.
  • фітнес : загальна заподіяна шкода
  • вартість : загальний витрачений час
  • гілки : будь-яке відоме заклинання. Якщо заклинання все ще перебуває в режимі закриття, просто додайте це значення до часу його відтворення.
  • мета : загальне здоров'я цілі. Мета повинна бути обмеженою кількістю збитків, тому у випадку невідомої цілі вибирайте якомога більше здоров’я.
    Крім того, мета може витратити менше 50 секунд, а пошук знайде максимальний збиток, який можна було б зробити за 50 секунд.

Підключіть ці параметри до Уніфікованого пошуку витрат (UCS) та presto, гарантованого оптимального плану бою. Ще краще, якщо ви можете придумати евристику, шукати за допомогою A * або IDA *, і ви отримаєте таку ж відповідь набагато швидше.

Ще кілька переваг використання UCS полягає в тому, що він може знайти оптимальний порядок лиття для набагато складніших ситуацій, ніж той, який вам надали лише 3 змінні. Деякі інші аспекти, які можна легко додати:

  • псування з часом
  • оновити заклинання, щоб зменшити час закриття інших заклинань
  • поспішний заклинання, що спричиняє швидше відтворення інших заклинань.
  • пошкоджуючий пристрій, спричиняючи інші заклинання, щоб зробити більше шкоди.

UCS не є всесильним. Він не може моделювати переваги захисних заклинань. Для цього вам доведеться перейти на пошук альфа-бета-версії або мінімакс.
Крім того, він не справляється із зоною впливу та груповими боями дуже добре. UCS можна налаштувати для надання розумних рішень у цих ситуаціях, не можна гарантувати оптимальне рішення.


2

Це спеціалізована проблема комбінаторної оптимізації. Зі збільшенням кількості заклинань, складність у пошуку оптимальної комбінації / структури заклинань значно збільшується. Евристика, подібна до тих, що використовуються для вирішення проблеми, була б корисною для вирішення цієї проблеми.


1

Вам потрібно думати з точки зору "збитку на одиницю часу відливання" (DPCT) - наприклад, вогнепальна куля з 3-секундним відливом і нанесення 3000 збитків зробила б 1000 DPCT.

Якщо вам довелося чекати 3 секунди на вимкнення, перш ніж викинути його, це призведе до зниження його до 500 DPCT (3000 збитків, розділене на 6 секунд, включаючи очікування)

Тому вам просто потрібно визначити час пошкодження за кожний час заклинання, включаючи будь-яке інше, що чекає на завершення роботи. Виберіть один із найвищим DPCT, зачекайте, якщо потрібно, а потім відкиньте його. Повторюйте, поки начальник не помер :)


проблема полягає в тому, що DPCT може бути дуже оманливим. Скажімо, наприклад, ми додаємо ще 2 заклинання до суміші Fireball: 3000 пошкоджень, 3 секунди кинутих, 6 секунд відключення, DPCT: 1000 Заклинання №2: 20 пошкоджень, 4 секунди кидок, 4 секунди відключення, DPCT: 5 Заклинання №3: 3 пошкодження, 3 секунди відкидання, 3 секунди відключення, DPCT: 1 (пам’ятайте, закриття починається з моменту заклинання) Навіть незважаючи на те, що у Заклинання №3 є нижчий DPCT, це призведе до вищого DPS (1-3-1-3. .) ніж Заклинання №2 (1-2-1-2 ...).
— aaronfarr

1

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

Ви завжди могли накласти інший елемент у рівняння. Мана / Магічні очки можуть служити цій цілі, дозволяючи гравцеві визначити, чи варто використання цих очок на користь.

В цілому, як сказав bluescrn, DPCT (або DPS як його називають у багатьох іграх, які дуже налаштовані та обговорюються гравцями, які шукають найкращу суміш) - це дійсно головний елемент, який ви хочете збалансувати, особливо якщо у вас є якісь Дерева технологій / навичок, які дозволяють різним гравцям прогресувати з різними навичками, але з можливістю наносити подібні збитки на даній позиції в грі.


0

З'ясував цей алгоритм, який добре працює в моїх цілях.

Люди підняли кілька чудових моментів. Надання кінцевих параметрів цілі дозволить нормальним алгоритмам пошуку зробити свою справу. тобто. робити оптимальний збиток за t секунд, робити x пошкодження в оптимальний час.

Мій алгоритм просто повертає послідовність заклинань з найвищим показником DPS. Це швидкий алгоритм, оскільки він зменшує розмір набору, який ви проїжджаєте, не вимагає знань щодо інших методів пошуку дерева.

Перший крок - визначити заклинання з найбільшим ураженням за кинутий час. Це заклинання стає "базовим" заклинанням, оскільки гарантуватиме найвищий збиток за секунду. Це означає, що ви завжди повинні запускати це заклинання, якщо виконуються наступні 2 умови: 1) Базова заклинання доступне (не перебуває в режимі відключення). 2) Ви зараз не заклинаєте.

Тоді це стає справою заповнення інших заклинань, поки базове заклинання перебуває у режимі відключення. Між (час виступу) і (час відключення - час відкидання). Однак може відбутися деяке перекриття (правило 2 вище помилкове).

Тоді стає питанням повторної роботи через усі не-базові заклинання, щоб знайти всі послідовності заклинань, які не порушують 2 правила.

За заклинання, які DO перекриваються, ви повинні покарати їх за потенційну шкоду, яку могло зробити базове заклинання (до максимального збитку).

Візьмемо для прикладу 2 заклинання

1: 300 пошкоджень, 3-х часовий час, 10-секундне відключення

2: 290 ушкоджень, 3с час кидання, 3с відключення

Найбільше збитків відбувається від послідовності 1 - 2 - 2 - 2. Що спричиняє перекриття на 2 секунди в потенційному №1 ролі. Однак це все-таки вигідно, оскільки якщо ви не кинете третє заклинання (тобто 1 - 2 - 2), ви нанесете 880 збитків за одну секунду. Якщо ви додасте додаткове заклинання №2, ви зробите 1170 - 2 секунди №1, що становить 200. Отже, 970 збитків - ваш відносний збиток.


-2

Ви можете зробити простий чохол стилю "рівень безпеки".

Це просто вгорі моєї голови, тому остерігайтеся логічних помилок, що перевищують рівень думки мого втомленого стану, але я сподіваюся, що це може вас почати.

Припустимо, що ваш час проводиться в цілих блоках -

// after casting spell
int remainingTime = (coolDown - castTime);
switch(spellJustCast)
{
  // assuming the cast method will have some input validation for whether the spell
  // is off cooldown or not, pass the time as a parameter
  case 3 : castSpell1(remainingTime);
           castSpell2(remainingTime);
           break;
  case 1 : castSpell2(remainingTime);
           castSpell3(remainingTime);
           break;
  case 2 : castSpell1(remainingTime);
           castSpell3(remainingTime);
           break;
  default: System.out.println("Debug!");
           break;
}

Деякі виклики методів є непотрібними через ваш час написання, але завжди є можливість для оновлень.

Редагування: Я щойно зрозумів, що вам потрібно буде скинути решту часу після передачі нового заклинання, ймовірно, найкраще зробити його атрибутом / полем класу та встановити його з виклику в методах castSpell.


Я дійсно не маю уявлення, до чого ви намагаєтеся потрапити, але жоден сучасний ігровий движок не має таких функцій, як castSpell1 і castSpell2.

1
@Joe Wreschnig Я мав на увазі їх як власні методи у своїх власних ігрових класах, це лише абстрактний приклад, а не детальний.
— kimully

1
Правильно, це не так, як спрацьовують заклинання в сучасних двигунах. Є одна функція castSpell, яка бере об’єкт, поля якого читаються з файлу. Таку заяву комутатора неможливо підтримати в будь-якому реальному двигуні, і потрібен якийсь алгоритм планування.

@Joe Wreschnig Я розумію. Я просто давав спосіб вирішити проблему. Цей приклад написаний на java, не призначений для двигуна чи конкретних рамок. Але якщо вона не може бути реалізована, як ви кажете, моя відповідь недійсна.
— kymully
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.