Автоорганізована / розумна система інвентаризації?


11

останній тиждень я працював над системою інвентаризації Unity3D. Спочатку я отримав допомогу від хлопців у Design3, але це було не так довго, поки ми не розкололи шлях, тому що мені дуже не сподобалося, як вони зробили свій код, у нього не було жодного запаху OOP.

Я зробив наступні кроки вперед - елементи займають більше одного слота, вдосконалена система розміщення (предмети намагаються зробити все можливе, щоб найкраще підійти), локальна система миші (миша потрапляє в пастку в зоні активного мішка) тощо

Ось демонстрація моєї роботи.

Те, що ми хотіли б мати у нашій грі, - це функція автоматичної організації, а не автоматичне сортування. Ми хочемо цю функцію, оскільки наш інвентар буде в режимі реального часу - не так, як в Resident Evil 1,2,3 і т.д. А тепер уявіть себе у стихій ситуації, оточеній зомбі, і у вас немає куль, ви озираєтесь, бачите, що поблизу на землі є кулі, тож ви йдете за ними і намагаєтеся забрати їх, але вони не не підходить! ви подивитеся на свій інвентар і дізнаєтесь, що якщо ви реорганізуєте деякі елементи, він підійде! - тепер гравець - у цій ситуації не встигає реорганізуватися, тому що він оточений зомбі і помре, якщо він зупиниться і організує інвентар для створення місця (запам’ятайте інвентар в режимі реального часу, не робивши пауз) - не хотів би ' t приємно, щоб це відбувалося автоматично? - Так!

(Я вважаю, що це було реалізовано в деяких іграх, таких як облога Dungeon або щось подібне, тому впевнений, що це можливо)

Погляньте, наприклад, на цю картинку:

Що робить автоматичне сортування

Так, якщо ви автоматично сортуєте проблему, ви отримаєте пробіли, але це погано, тому що: 1– Дорога: для звільнення цих пробілів не потрібна ціла операція сортування, на першому малюнку просто пересуньте червоний елемент на знизу вліво, і ви отримуєте ті самі пробіли, які отримали від автоматичного сортування. 2- Це гравцеві дратує: "Хто F сказав вам, щоб ви замовили мої речі?"

Я не прошу "Як написати код" для цього, я просто прошу деякі вказівки, куди шукати, які алгоритми задіяні? Це щось пов’язане з графіками та найкоротшими матеріалами шляху? Я сподіваюся, не тому, що мені не вдалося продовжити навчання в коледжі: / Але навіть якщо це так, просто скажіть мені, і я дізнаюся, що стосується цього.

Зауважте, що може бути більше ніж одне рішення. Тому я здогадуюсь, що перше, що я повинен зробити, - це зрозуміти, чи ситуація є "вирішуваною" - якщо я знаю, як визначити, ситуація вирішувана чи ні, то я можу "вирішити" її. Мені просто потрібно знати умови, які роблять це "вирішуваним". І я вважаю, що для цього повинен бути якийсь алгоритм / структура даних.

Ось картинка для декількох рішень спроби вмістити елемент 1x3:

введіть тут опис зображення

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

Зауважте, що якщо я витрачу на це час, я придумаю спосіб її вирішити, але це був би не найкращий спосіб, це як, тримаючи колесо автомобіля ногами замість рук! XD Або просто, як намагатися вирішити проблему, яка потребує масивів, але ви ще не знаєте про їх існування! То який правильний підхід до цього?

Оновлення з коментаря

@Stephen Я справді не є гуру в Alogs, ви згадали про «рюкзак» та @BlueRaja - Денні Пфлюгхофт згадав про альго-2D-упаковку. Вони якось споріднені / однакові? - Я все ще розгублений, як слід підходити до цього.

Так, я вже використовую "евристику", але я не знав, що це таке: D він знаходить перший доступний слот, і дивись, чи підходить цей предмет.

Я не знаю, чи вдасться замовити елементи на основі їх «громіздкості» (яку я називаю nSlotsRequired = nRowsReq * nColsRec), оскільки у вас є, наприклад, елементи 2х2 та 1x4, вони мають однакову об'ємність, але різні форми і матимуть по-різному впливає на те, як пройдуть інші предмети. ТАК... :/

Я переглянув це відео, мені дуже сподобалась ідея упаковки, але мені цікаво, як це зробити, оскільки інвентар 2D. Я навіть не впевнений, що пакування бін є ключовим тут, бо, правда, я можу мати більше ніж один мішок, але в нашій грі це буде просто один мішок. Отже, справа в тому, щоб помістити предмети в «одну» сумку і не більше того. Тож приклади в цьому відео (труби та шини) насправді не відповідають моїй проблемі. Також переглянув деякі речі про цю рюкзаку, я не побачив, як "значення" пов'язане з моїми предметами / інвентарем, але я здогадуюсь, що "вага" такий же, як громіздкість, не впевнений.


7
Це 2D упаковка для сміття, яка є NP-Complete. Отже, будь-який алгоритм, який підкаже вам, чи можете ви вмістити всі предмети, буде неефективним (в гіршому випадку). Однак ви можете знайти кілька непоганих алгоритмів наближення.
BlueRaja - Danny Pflughoeft

Саме тому я зважився на (більш поширену в ці дні) модель інвентаризації типу «один слот на предмет» замість цієї. Я б хотів, щоб у вас було рішення, я відмовився від цієї проблеми ...
Ryno,

@ BlueRaja-DannyPflughoeft Цікаво, чи є простий / ефективний алгоритм, якщо елементи обмежувались певними формами?
congusbongus

Обмеження фігур не зменшує складність, а просто полегшує роздуми, щоб ви вважали, що складність вирішена, afaik.
Патрік Х'юз

@VeXe Вибачте, я пропустив оновлення щодо вашого питання. Упаковка для сміття та рюкзак - це не те саме. Але обидва - проблеми з упаковкою. «Значення» у вашому випадку - це форма та розмір ваших товарно-матеріальних цінностей.
Стівен

Відповіді:


8

Це варіація проблеми з рюкзаком. Як згадує Денні Плугхофт, це NP-Complete. Це означає, що це неможливо вирішити в лінійний час, якщо я правильно пам’ятаю.

Але ви можете спробувати вирішити це в кілька етапів. Це в основному проблема сортування.

Я б почав з обчислення "об'ємності" кожного елемента: це можна обчислити декількома способами:

  • громіздкість = макс (довжина, ширина);

  • громіздкість = довжина * ширина

  • громіздкість = sqrt (довжина * ширина)

Потім почніть класти предмети з найвищим балом спочатку в інвентар. Оскільки вони, швидше за все, пізніше не впишуться в залишок місця. Дрібні предмети підійдуть завжди.

Для вашої стратегії розміщення вам потрібен евристичний (фантазійне ім’я для освічених здогадок ;-)). Щось на кшталт спроби помістити предмети в перший вільний слот зліва вліво або щось подібне.

Стратегія сортування інвентарів Diablo II працювала дещо схоже, я думаю. Такі речі, як мечі та списи, закінчуватимуться вгорі ліворуч, потім одяг та обладунки, потім пряжка тощо.

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


1
NP-завершений - це набір проблем зі складністю вище полінома. Для відносно невеликого запасу (менше тисячі позицій я б сказав :)) навіть експоненціальний алгоритм спрацював би досить швидко, оскільки один крок такого алгоритму займає дуже мало часу. Проте використання вашої ідеї повинно бути досить хорошим та простішим, ніж впровадження алгоритму динамічного програмування -> +1
MartinTeeVarga

THX за підсумковий результат. Так, інвентар не повинен бути потенційно нескінченним, тому експоненціальні алгоритми повинні нормально працювати ^^
Стівен

@ sm4: тисяча, як правило, величезна кількість для NP-Complete проблем. Пам'ятайте, ці проблеми є O (2 ^ n) - навіть просто 2 ^ 64 обчислювально нездійсненно!
BlueRaja - Danny Pflughoeft

3

Ха-ха, @ всі, хто допоміг, дякую. Мені вдалося остаточно вирішити це. Ось що я в основному зробив:

IEnumerator AddItem_Sorted (Item item)
  1. Тривіальна умова: перевірте, чи є у нас мінімум nRequiredSlots для того, щоб елемент помістився, чи є в нас, продовжуйте ...
  2. ми випорожнимо всю сумку - поставивши предмети в заповнювач (список чи щось)
  3. додайте потрібний предмет до ДУЖЕ останнього місця / місця, до якого він міг би поміститися, переконайтесь, що він впевнений у своїй горизонтальній формі
  4. використовуючи зменшене альго першої форми, ми додамо решту наших предметів
  5. під час додавання ми будемо використовувати динамічне програмування (запам'ятовування), щоб пам’ятати той індекс, який ми додаємо (індекс наступного доступного слота)
  6. якщо все додавання є успіхом, нам вдалося підігнати потрібний предмет і якось сортувати сумку - від великих до дрібних предметів
  7. якщо ми не змогли додати всі предмети, це означає, що це не було вирішуваною ситуацією, тому ми повинні перенести сумку до попереднього стану
  8. Один із способів зробити це (вийшов з поверхні моєї думки) - скопіювати стан мішка перед цілим заходом, і тоді, якщо це не вдасться, ми підключимося до цього попереднього стану, а ще краще, під час ' випорожнивши сумку, ми запам'ятовуємо, де був кожен предмет, так що, якщо оп не вдасться, ми повернемо їх назад - за допомогою AddItem (item, index) - за попередніми індексами :)
  9. весь цей процес може зайняти час, тому ми могли розділити навантаження на окремі кадри, використовуючи мій прекрасний вихід :)
  10. Зроблено ! \ м / (@ ~ 9: 00)

ОНОВЛЕННЯ:

  1. Я створив масив, який зберігав індекси всіх доданих елементів, тому мені не потрібно йти і шукати зайняті слоти, щоб звільнити мене - великий приріст.

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

Як видно з відео, для цього потрібно трохи оптимізувати, сортування не є ідеальним, я хотів би використовувати повну упаковку у контейнери, але це вже жадібно до продуктивності. Я відкритий до будь-яких пропозицій щодо оптимізації, ще раз дякую :)


Ласкаво просимо! :) Хочу подякувати BlueRaja - Danny Pflughoeft за те, що він згадав про упаковку у сміттєві контейнери, @Stephen за ідею громіздкості та Річард Бакленд за його лекцію з динамічного програмування та всі лекції.
vexe
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.