Pacman: як очі знаходять назад у чудовисько?


321

Я знайшов багато посилань на ШІ привидів у Пакмані, але жоден з них не згадував, як очі знаходять дорогу назад до центральної ями-привидів після того, як привид з'їдає Пакмана.

У своїй реалізації я реалізував просте, але жахливе рішення. Я просто важко кодував на кожному куті, в якому напрямку слід піти.

Чи є краще / чи найкраще рішення? Може бути загальний, який працює з різними рівнями дизайну?


11
Ви впевнені, що жорстке кодування на куті досить добре? Це не гарантує найкращого маршруту. Уявіть, що привид стикається з довгим вузьким проходом. За вашим алгоритмом йому довелося б спустити весь цей прохід, дійти до кута, а потім пройти найшвидший маршрут. Якщо ви кодуєте кожен квадрат, в якому напрямку рухатися, він, можливо, знатиме, щоб просто повернути спочатку.
Марк Петерс

3
@ Марк, залежить від вашого визначення кута. Якщо це T-з'єднання, навіть якщо ви просто переходите прямо у верхній рядку, це добре.
Thorbjørn Ravn Andersen

1
@ Thorbjørn: Я навіть не кажу про перехрестя. Погляньте на цю дошку: en.wikipedia.org/wiki/File:Pac-man.png . Якби привид рухався праворуч і розміщувався на другій крапці знизу вліво, він деякий час не зустрічав би жодного перетину. Це призведе до того, що він просунеться на 10 квадратів далі, ніж якби він повернув назад (ліворуч) і пішов найкоротшим шляхом.
Марк Петерс

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

1
дякую за всі відповіді! Я просто дотримувався свого попереднього рішення і твердо кодував вказівки на кожному куті. Щоб зробити це загальним, потрібно, щоб leveldesigner / файл рівня також визначав цю інформацію у визначенні рівня.
RoflcoptrException

Відповіді:


152

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

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

EDIT (11 серпня 2010 р.): Мене щойно згадували на дуже детальній сторінці системи Pacman: Досьє Пак-Людини , і оскільки у мене тут прийнята відповідь, я відчув, що повинен її оновити. Ця стаття, схоже, не висвітлює акт повернення до будинку чудовиськ, але в ній йдеться про те, що пряме просування в Pac-Man є випадком наступного:

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

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

3
Так, або якщо є інструмент для створення карт, як частина цього.
Кілотан

6
Немає нічого поганого в попередньому обчисленні зворотних шляхів. Ви торгуєте сховищами (шляхами) для виконання часу виконання.
Стів Куо

6
Дякую. Я думаю, що я дотримуюся цього рішення. Хтось знає, як це робилося в оригінальному Pacman?
RoflcoptrException

4
Ні, я ні. Первісне питання використовував цей термін, але це не зовсім юридично обов'язково.
Килотан

85

Я вирішив цю проблему для загальних рівнів таким чином: Перш ніж рівень починається, я роблю якусь "заливку" з лунки монстра; кожна плитка лабіринту, яка не є стіною, отримує число, яке говорить про те, наскільки це далеко від отвору. Отже, коли очі на плитку з відстані 68, вони дивляться, яка з сусідніх плиток має відстань 67; це тоді шлях.


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

1
Щоб заощадити простір (для великих світів або обмежених систем), ви можете зберегти напрямок руху на кожному перехресті, а не економити значення для кожної плитки. Це по суті те, що пропонувала ОП.
BlueRaja - Danny Pflughoeft

BlueRaja: Звичайно, але це складніше зробити це, і результат не такий оптимальний - привид з'їдається між двома перехрестями, тож він може деякий час бігти в неправильний бік. Моє рішення добре працювало на en.wikipedia.org/wiki/HP_200LX, тож наскільки це може бути більш обмеженим?
Еріх Кітцмюллер

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

Матьє: Так, це була б можлива оптимізація.
Еріх Кітцмюллер

42

Для альтернативи більш традиційним алгоритмам накладання маршрутів , ви можете поглянути на (відповідно названий!) Шаблон Pac-Man Scent Antiobject .

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

Після встановлення запаху вартість виконання дуже низька.


Редагувати: на жаль, стаття з Вікіпедії видалена, тож WayBack Machine допоможе ...


2
це буде моєю відповіддю. Це те саме, що у ammoQ, але я завжди пам’ятаю про запах Pacman :)
Люк Шафер

Схоже, стаття з Вікіпедії мертва / видалена. Найпопулярніший результат google - це нитка, але я думаю, що це наближається.
Девід

2
Я на секунду розгубився, але потім враз зрозумів, що означає "аромат". Це такий чудовий спосіб описати ці скалярні польові речі!
Стівен Лу


18

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

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

IMO, якщо він не зламаний, не виправляйте його.

EDIT

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

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

(Убік: якщо маршрути налаштовані вручну, дизайнер лабіринтів може зробити рівень цікавішим, використовуючи неоптимальні маршрути ...)


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

можна також генерувати лабіринти (у мене є алгоритм, який генерує приємні лабіринти Pacman), тому трохи автоматизації - це шлях
Еріх Кітцмуеллер,

"... або користувачі можуть їх проектувати." У такому випадку у вас DO є мільярд лабіринтів.
phuzion

@phuzion - я це знаю. Однак між двома випадками існує різниця. Якщо саме ОП створює лабіринт базіліона, то створювати маршрутизацію вручну незручно. Якщо він є кінцевим користувачем ... це означає, що ОП має написати документацію, виконувати нескінченні проблеми лабіринтів кінцевих користувачів, нескінченні скарги на те, наскільки це недоброзичливо, тощо. Іншими словами, причини впровадження автоматичної генерації маршруту різні .
Стівен С

14

У первісному Pacman the Ghost знайшов жовтого пігулка їдцем за його "запахом", він залишить слід на карті, привид буде блукати навмання, поки вони не знайдуть запах, тоді вони будуть просто слідувати шлях запаху, який веде їх безпосередньо до гравець. Щоразу, коли Pacman рухався, "значення запаху" зменшувалися б на 1.

Тепер простим способом повернути весь процес було б мати "піраміду запаху примари", яка має найвищу точку в центрі карти, тоді привид просто рухається в напрямку цього запаху.


Мені дуже подобається такий підхід, і я також спробую цей
RoflcoptrException

5
Це не правильно; якби вони всі дотримувались цього алгоритму, вони б переслідували єдиний файл. Поведінка кожного привида різна; ви можете знайти більше інформації у статті Вікіпедії.
дільник

5

Якщо припустити, що у вас вже є логіка, необхідна для переслідування Pacman, чому б не використати це повторно? Просто змініть ціль. Здається, це було б набагато менше роботи, ніж намагатися створити зовсім новий розпорядок, використовуючи абсолютно ту ж логіку.


так, у мене є логіка переслідувати Pacman вже реалізована, але я також не задоволений цим;)
RoflcoptrException

На моєму досвіді (я люблю писати версії Pacman просто заради розваги), це може призвести до того, що очі надовго застрягнуть поза отвором. Це тому, що алгоритм переслідування, як правило, йде по лінії "якщо pacman знаходиться на півночі, іди на північ", але лабіринт може містити "пастки", куди очі повинні були б спершу піти на південь. Оскільки Pacman рухається, привид рано чи пізно втече, але отвір є нерухомою ціллю. (Примітка: я говорю про створені лабіринти)
Еріх Кітцмуеллер


3

Як щодо кожного квадрата, який має значення відстані до центру? Таким чином, для кожного заданого квадрата можна отримати значення квадратів найближчих сусідів у всіх можливих напрямках. Ви вибираєте квадрат з найнижчим значенням і переходите до цього квадрата.

Значення будуть попередньо обчислені за допомогою будь-якого доступного алгоритму.


Я збирався запропонувати це. Зовнішня заливка, що починається з «чудовисько-нори». Я думаю, що ваша відповідь виграє картину.
AjahnCharles

3

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

http://gameai.com/wiki/index.php?title=Pac-Man#Respawn Коли привиди вбиваються, їхні зневірені очі повертаються у вихідне місце. Це просто здійснюється, встановивши цільову плитку привидів у цьому місці. Навігація використовує ті самі правила.

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

Побічна примітка: Я не усвідомлював, наскільки дивовижними були ці програмісти pac-man, якщо вони в основному створили всю систему повідомлень у дуже маленькому просторі з дуже обмеженою пам'яттю ... це дивно.


2

Я думаю, що ваше рішення підходить до проблеми, простішої, ніж це, зробити нову версію більш "реалістичною", де очі привидів можуть пройти крізь стіни =)


2
Щоб додати ще більше реалізму, дозвольте самим примарам мати можливість переміщатися крізь стіни: D
Thomas Eding

3
Це непрозорі стіни привидів, але привиди другого порядку (привид примари) більш прозорі. (ви можете знайти багато посібників користувача з помилками, перетвореними у функціях)
Hernán Eche

1
+1 для "привидів другого порядку" - о так, похідне від привидів, безумовно, повинно перевищувати прості об'єкти першого порядку, як стіни ... :)
Асад Ебрагім

2

Ось аналог та псевдокод до ідеї заповнення заповнення ammoQ.

queue q
enqueue q, ghost_origin
set visited

while q has squares
   p <= dequeue q
   for each square s adjacent to p
      if ( s not in visited ) then
         add s to visited
         s.returndirection <= direction from s to p
         enqueue q, s
      end if
   next
 next

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


2

Я мало знаю, як ви реалізували свою гру, але ви можете зробити наступне:

  1. Визначте розташування очей щодо положення воріт. тобто це ліворуч вище? Прямо внизу?
  2. Потім перемістіть очі навпроти одного з двох напрямків (наприклад, змусьте його рухатись ліворуч, якщо справа від воріт, і нижче воріт) і перевірте, чи є стіни, що заважають вам це робити.
  3. Якщо є стіни, які заважають вам це робити, тоді змусьте його рухатись навпроти іншого напрямку (наприклад, якщо координати очей відносно штифта праворуч на північ і він в даний час рухається ліворуч, але стіна, як зробити це, рухатися на південь.
  4. Не забудьте постійно перевіряти переміщення, щоб постійно перевіряти, де очі розташовані відносно воріт, і перевіряйте, чи немає широтної координати. тобто це лише над воротами.
  5. У випадку, якщо тільки ворота рухаються вниз, якщо є стіна, рухайтеся ліворуч або праворуч і продовжуйте робити це число 1 - 4, поки очі не будуть в лігві.
  6. Я ніколи не бачив тупику в Pacman, цей код не враховує тупики.
  7. Крім того, я включив рішення, коли очі будуть «коливатися» між стіною, яка переходить на походження в моєму псевдокоді.

Деякі псевдокоди:

   x = getRelativeOppositeLatitudinalCoord()
   y
   origX = x
    while(eyesNotInPen())
       x = getRelativeOppositeLatitudinalCoordofGate()
       y = getRelativeOppositeLongitudinalCoordofGate()
       if (getRelativeOppositeLatitudinalCoordofGate() == 0 && move(y) == false/*assume zero is neither left or right of the the gate and false means wall is in the way */)
            while (move(y) == false)
                 move(origX)
                 x = getRelativeOppositeLatitudinalCoordofGate()
        else if (move(x) == false) {
            move(y)
    endWhile

2

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

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

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


2

Коротка відповідь, не дуже добре. :) Якщо ви зміните лабіринт Pac-man, очі не обов'язково повернуться. Деякі з хаків, що плавають навколо, мають цю проблему. Тож це залежить від того, щоб мати лабіринт кооперативу.


2

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


2
цей шлях, швидше за все, буде занадто довгим
Ахмад Ю. Салех

Щоразу, коли ви переглядаєте вузол, ви можете усунути цикл з історії. Це зробило б це трохи більш прямим. Можливо, це буде цікавіше, ніж завжди слідувати тим самим прямим шляхом, але досить часто воно буде включати в себе досить нерозумні майже петлі (наприклад, 3 сторони квадрата).
AjahnCharles

1

Знаючи, що шляхи Pacman є невипадковими (тобто кожен конкретний рівень 0-255, чорнильний, блимаючий, рожевий та клайд буде працювати точно такий же шлях для цього рівня).

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


1

Привиди в Pacman слідують більш-менш передбачуваним зразкам з точки зору спроб спочатку зрівнятися на X або Y, поки мета не буде досягнута. Я завжди припускав, що це точно так само для очей, які знаходять дорогу назад.


1
  1. Перед початком гри збережіть на карті вузли (перехрестя)
  2. Коли монстр помирає, візьміть точку (координати) і знайдіть найближчий вузол у своєму списку вузлів
  3. Обчисліть усі шляхи, починаючи від цього вузла до отвору
  4. Пройдіть найкоротший шлях по довжині
  5. Додайте довжину простору між точкою та найближчим вузлом
  6. Малюйте і рухайтеся по стежці

Насолоджуйтесь!


1

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

Мітки вузлів один раз

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

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

public void fillMap(List<Node> nodes) { // call passing lairNodes
    int i = 0;

    while(nodes.count > 0) {
        // Label with distance from lair
        nodes.labelAll(i++);

        // Find connected unlabelled nodes
        nodes = nodes
            .flatMap(n -> n.neighbours)
            .filter(!n.isDistanceAssigned());
    }
}

Затоплення з лігва

Очі рухаються до сусіда з найменшою міткою

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

public Node moveEyes(final Node current) {
    return current.neighbours.min((n1, n2) -> n1.distance - n2.distance);
}

Повністю мічений приклад

Повна карта


0

Для моєї гри PacMan я зробив дещо "shortest multiple path home " алгоритм, який працює для будь-якого лабіринту, який я йому надаю (в рамках мого набору правил). Він також працює через їх тунелі.

Коли рівень завантажений, все path home data in every crossroadпорожнє (за замовчуванням), і як тільки примари почнуть досліджувати лабіринт, вони crossroad path home informationпостійно оновлюються щоразу, коли натрапляють на "нову" перехрестя або з іншого шляху, натрапляють на їх відому перехрестя.


-2

Оригінальний Pac-Man не використовував пошук шляхів або фантазійний ШІ. Це просто змусило геймерів вважати, що в ньому є більше глибини, ніж насправді, але насправді це було випадково. Як зазначено в Artificial Intelligence for Games / Ian Millington, John Funge.

Не впевнений, правда це чи ні, але це має для мене багато сенсу. Чесно кажучи, я не бачу такої поведінки, про яку говорять люди. Red / Blinky for ex не слідкує за гравцем, як кажуть. Здається, ніхто спеціально не послідовно слідкує за гравцем. Шанс, що вони підуть за вами, здається мені випадковим. І дуже спокусливо бачити поведінку у випадковому стані, особливо коли шанси переслідувати дуже високі, з 4 ворогами і дуже обмеженими варіантами повороту, на невеликому просторі. Принаймні, у своїй початковій реалізації гра була надзвичайно проста. Ознайомтеся з книгою, вона знаходиться в одній з перших глав.


так, він використовував деякий AI. І так, Blinky слідує за Pacman, коли він перебуває в режимі погоні (час від часу перемикається на нього), тож все в порядку
Жан-Франсуа Фабре
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.