Pacman: как глаза возвращаются к дыре монстра?

Я нашел много ссылок на ИИ призраков в Пакмане, но никто из них не упомянул о том, как глаза возвращаются в центральную дырку призраков после того, как Пэкман съедает призрак.

В моей реализации я реализовал простое, но ужасное решение. Я просто жестко закодирован на каждом углу, в котором должно быть сделано.

Есть ли лучшее/лучшее решение? Может быть, общий, который работает с разными уровнями дизайна?

Ответ 1

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

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

EDIT (11 августа 2010 года): меня просто назвали очень подробной страницей в системе Pacman: Досье Pac-Man и так как у меня есть принятый ответ здесь, я чувствовал, что должен его обновить. В статье, как представляется, не говорится о возврате в дом монстра явно, но в нем говорится, что прямой путь в Pac-Man - это случай следующего:

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

Ответ 2

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

Ответ 3

Для альтернативы более традиционным алгоритмам поиска пути вы можете взглянуть на (соответствующим образом названный!) Паттерн Anti-object с запахом Pac-Man.

Вы можете рассеять запах чудовищных дыр вокруг лабиринта при запуске и следить за ним дома.

Как только запах установлен, стоимость исполнения очень низкая.


Изменить: печально, статья wikipedia была удалена, поэтому WayBack Machine на помощь...

Ответ 4

Вы должны посмотреть алгоритм pathfindings, например Алгоритм Dijsktra или A * алгоритм. В этом и заключается ваша проблема: проблема с графом/пути.

Ответ 5

Любое простое решение, которое работает, является ремонтопригодным, надежным и работает достаточно хорошо, является хорошим решением. Это звучит так, как будто вы уже нашли хорошее решение...

Решение по поиску путей, вероятно, будет более сложным, чем ваше текущее решение, и, следовательно, более вероятно, потребуется отладка. Вероятно, он также будет медленнее.

IMO, если он не сломан, не исправляйте его.

ИЗМЕНИТЬ

IMO, если лабиринт исправлен, то ваше текущее решение - это хороший/элегантный код. Не делайте ошибки приравнивания "хорошего" или "элегантного" к "умному". Простой код также может быть "хорошим" и "элегантным".

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

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

Ответ 6

В оригинальном Pacman Ghost нашел желтого питомника по его "запаху", он оставил след на карте, призрак блуждал беспорядочно, пока не обнаружил запах, после чего они просто следуют по пути запаха, который ведет их непосредственно игроку. Каждый раз, когда Pacman перемещался, "значения запаха" уменьшались бы на 1.

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

Ответ 7

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

Ответ 9

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

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

Ответ 10

Я думаю, что ваше решение подходит именно для этой проблемы, проще, чем сделать, сделать новую версию более "реалистичной", где глаза-призрак могут проходить сквозь стены =)

Ответ 11

Здесь добавлена ​​идея заливки аналогового и псевдокода в 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 (N), я действительно верю.

Ответ 12

Я не знаю, как вы реализовали свою игру, но вы можете сделать следующее:

  • Определите относительное положение местоположения глаз к воротам. то есть он оставлен выше? Прямо внизу?
  • Затем переместите глаза напротив одного из двух направлений (например, заставьте его двигаться влево, если он находится справа от ворот и под воротами) и проверьте, есть ли там и стены, препятствующие этому.
  • Если есть стены, препятствующие тому, чтобы вы делали это, сделайте это движением напротив другого направления (например, если координаты глаз относительно штифта находятся справа на север, и в настоящее время он движется влево, но есть стена в путь сделать его двигаться на юг.
  • Не забудьте постоянно проверять, чтобы двигаться, чтобы проверить, где находятся глаза относительно ворот, и проверить, нет ли широтной координаты. то есть он находится только над воротами.
  • В случае, если только ворота закрываются, если есть стена, двигайтесь либо влево, либо вправо и продолжайте делать это число 1 - 4, пока глаза не окажутся в логове.
  • Я никогда не видел тупика в Pacman, этот код не будет учитывать тупики.
  • Кроме того, я включил решение, когда глаза будут "качаться" между стеной, которая проходит через источник в моем псевдокоде.

Некоторые псевдокоды:

   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

Ответ 13

Я бы предложил, чтобы призрак сохранил путь, который он взял из отверстия в Pacman. Итак, как только призрак умрет, он может следовать за этим сохраненным путем в обратном направлении.

Ответ 14

dtb23 предлагает просто выбрать случайное направление в каждом углу, и в итоге вы обнаружите, что звуки чудовищных дыр ужасно неопределены.

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

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

Ответ 15

Это был лучший источник, который я смог найти о том, как он действительно работал.

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

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

Боковое замечание: я не понимал, насколько удивительны эти программисты из pac-man, они в основном создали целую систему сообщений в очень маленьком пространстве с очень ограниченной памятью... это потрясающе.

Ответ 16

Короткий ответ, не очень хорошо.:) Если вы измените лабиринт Pac-man, глаза не обязательно вернутся. У некоторых из хаков, плавающих вокруг, есть эта проблема. Таким образом, это зависит от наличия совместного лабиринта.

Ответ 17

Зная, что пути pacman неслучайны (т.е. каждый конкретный уровень 0-255, inky, blinky, pinky и clyde будут работать точно таким же путем для этого уровня).

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

Ответ 18

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

Ответ 19

  • Перед началом игры сохраните узлы (пересечения) на карте
  • Когда монстр умирает, возьмите точку (координаты) и найдите ближайший node в вашем node списке
  • Рассчитайте все пути, начиная с этого node до отверстия
  • Возьмите кратчайший путь длиной
  • Добавьте длину пробела между точкой и ближайшим node
  • Рисовать и перемещаться по пути

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

Ответ 20

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

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

Ответ 21

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

Узлы ярлыков

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

Я предполагаю, что у вас уже есть объекты, представляющие каждый node, и соединения со своими соседями. Псевдокод может выглядеть примерно так:

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());
    }
}

Наводнение из логовища

Глаза Переход к соседству с наименьшей меткой расстояния

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

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

Полностью маркированный пример

Полная карта

Ответ 22

Оригинальный пак-человек не использовал поиск путей или фантазии AI. Это просто заставило геймеров полагать, что для этого есть больше глубины, чем на самом деле, но на самом деле это было случайным. Как сказано в "Искусственном интеллекте для игр" /Ян Миллингтон, Джон Фундж.

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