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


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.