팩맨 : 눈은 어떻게 몬스터 홀로 돌아가는가?


321

나는 팩맨에서 귀신의 인공 지능에 대한 많은 언급을 찾았지만, 팩맨이 귀신을 먹은 후 어떻게 눈이 어떻게 중심 귀신 구멍으로 돌아가는지 언급하지 않았습니다.

내 구현에서 간단하지만 끔찍한 솔루션을 구현했습니다. 나는 어느 방향으로 가야할지 구석 구석에 하드 코딩했다.

더 나은 / 또는 최고의 솔루션이 있습니까? 다른 수준의 디자인에서 작동하는 일반적인 것일 수도 있습니다.


11
코너의 하드 코딩이 충분합니까? 이것이 최선의 경로를 보장하지는 않습니다. 유령이 길고 좁은 통로를 향하고 있다고 상상해보십시오. 당신의 알고리즘에 의해 그는 전체 통로를 내려 가서 모퉁이에 도달 한 다음 가장 빠른 경로 가져 가야합니다. 당신이 어느 방향으로 갈지 정사각형 에 하드 코딩했다면 , 그는 먼저 돌아가는 것을 알고있을 것입니다.
Mark Peters

3
@Mark, 코너에서의 정의에 따라 다릅니다. 맨 윗줄로 똑바로가더라도 T 연결이면 괜찮습니다.
Thorbjørn Ravn Andersen

1
@ Thorbjørn : 교차로에 대해서도 이야기하고 있지 않습니다. 이 보드를보십시오 : en.wikipedia.org/wiki/File:Pac-man.png . 고스트가 오른쪽으로 움직이고 왼쪽 아래에서 두 번째 점에 위치하면 잠시 동안 만나지 않습니다. 그것은 뒤로 (왼쪽) 돌아서 가장 짧은 길을 갔을 때보 다 10 칸 더 이동하게합니다.
Mark Peters

6
귀하의 솔루션은 웨이 포인트 (또는 빵 부스러기)를 사용하며 경로 찾기 알고리즘의 속도를 높이는 데 일반적으로 사용되는 기술이라고 생각합니다.
Nick Dandoulakis

1
모든 답변에 감사드립니다! 방금 이전 솔루션을 고수하고 모든 구석에 지시 사항을 하드 코딩했습니다. 일반적으로 레벨 디자이너 / 레벨 파일은 레벨 정의에서이 정보를 정의해야합니다.
RoflcoptrException

답변:


152

실제로, 나는 당신의 접근 방식이 어떤 길 찾기와 비교하여 거의 제로 실행 시간 비용을 가진 매우 멋진 솔루션이라고 말하고 싶습니다.

임의의 맵으로 일반화 해야하는 경우 경로 탐색 알고리즘을 사용할 수 있습니다-예를 들어 너비 우선 검색은 구현하기 간단합니다.이를 사용하여 게임을 실행하기 전에 각 모서리에서 인코딩 할 방향을 계산하십시오.

편집 (2010 년 8 월 11 일) : 나는 Pacman 시스템 : Pac-Man Dossier 에 대한 매우 자세한 페이지를 방금 언급했으며 여기에 허용 된 답변이 있으므로 업데이트해야한다고 생각했습니다. 이 기사는 괴물 집으로 돌아가는 행위를 명시 적으로 다루지 않는 것으로 보이지만 Pac-Man의 직접적인 길 찾기는 다음과 같은 경우입니다.

  • 다음 교차로로 계속 이동하십시오 (이것은 본질적으로 '선택이 주어지면 다음 단계에서 볼 수 있듯이 방향을 바꾸지 않는 방향을 선택하십시오);
  • 교차로에서 방금 나간 출구를 제외하고 인접한 출구 광장을보십시오.
  • 목표에 가장 가까운 것을 고릅니다. 둘 이상의 목표에 동일하게 근접한 경우 첫 번째 유효한 방향을 위, 왼쪽, 아래, 오른쪽 순서로 선택하십시오.

16
그는 런타임에 (레벨이로드 될 때 재생을 시작하기 전에) 한 번만 계산할 수 있다고 생각 합니다. 유지하기가 어렵지 않습니다.
Mark Peters

3
예, 또는지도를 작성하기위한 도구가 있다면 그 일부입니다.
Kylotan 2016 년

6
리턴 경로를 사전 계산하는 데 아무런 문제가 없습니다. 런타임 성능을 위해 스토리지 (경로)를 거래하고 있습니다.
Steve Kuo

6
감사. 나는이 해결책을 고수 할 것이라고 생각한다. 원래 팩맨에서 어떻게했는지 아는 사람이 있습니까?
RoflcoptrException

4
아뇨 원래의 질문은 그 용어를 사용했지만 정확히 법적 구속력이있는 것은 아닙니다.
Kylotan 2012 년

85

나는 이런 식으로 일반적인 레벨에 대해이 문제를 해결했다. 레벨이 시작되기 전에 몬스터 홀에서 일종의 "홍수 채우기"를한다. 벽이 아닌 미로의 모든 타일은 구멍에서 얼마나 멀리 떨어져 있는지를 나타내는 숫자를 얻습니다. 따라서 눈이 68 거리 인 타일 위에있을 때, 이웃 타일 중 67 거리가있는 타일을 찾습니다. 그렇게하는 방법입니다.


15
예. 범람은 세상이 그렇게 커지지 않는 상황에서 길 찾기에 매우 좋습니다. 연결성이 미리 계산 된 더 굵은 격자를 사용하여 큰 세계에서도 사용할 수 있다고 생각합니다. 상황을 약간 벗어나게 만들지 만 그러한 게임에서 본 교통 체증보다 낫습니다.
Loren Pechtel

1
더 큰 세계 또는 제한된 시스템의 경우 공간을 절약하기 위해 모든 타일의 값을 저장하지 않고 모든 교차로에서 이동하는 방향을 저장할 수 있습니다. 이것은 본질적으로 OP가 제안한 것입니다.
BlueRaja-Danny Pflughoeft

BlueRaja : 물론 이죠.하지만 그렇게하는 것이 더 복잡하고 결과가 최적이 아닙니다. 유령은 두 교차로 사이에서 먹기 때문에 한동안 잘못된 방향으로 뛸 수 있습니다. 내 솔루션은 en.wikipedia.org/wiki/HP_200LX 에서 잘 작동 했기 때문에 얼마나 더 제한을받을 수 있습니까?
Erich Kitzmueller

5
(늦습니다 ...) 예 플러드 채우기는 좋지만 실제로는 다음 숫자를 사용하기 위해 각 숫자의 방향 (2 비트)이 필요하지 않습니다.
Matthieu M.

Matthieu : 예, 가능한 최적화 일 것입니다.
Erich Kitzmueller

42

보다 전통적인 경로 찾기 알고리즘에 대한 대안으로 Pac-Man Scent Antiobject 패턴을 살펴볼 수 있습니다 (적절하게 명명 된!) .

스타트 업시 미로 주변의 괴물 구멍 냄새를 확산시켜 눈으로 집을 따라갈 수 있습니다.

냄새가 설정되면 런타임 비용이 매우 낮습니다.


편집 : 슬프게도 wikipedia 기사가 삭제되었으므로 WayBack Machine이 구조되었습니다 ...


2
이것은 내 대답이 될 것입니다. 그것은 본질적으로 ammoQ와 동일하지만, 나는 항상 팩맨 냄새에 대해 기억합니다 :)
Luke Schafer

위키 백과 기사가 죽었거나 삭제 된 것 같습니다. 최고의 Google 결과는이 스레드이지만 이것이 가깝습니다.
David

2
나는 잠시 혼란 스러웠지만 "향기"의 의미를 즉시 이해했다. 이 스칼라 필드를 설명하는 좋은 방법입니다!
Steven Lu


18

작동하는 간단한 솔루션은 유지 관리 가능하고 신뢰할 수 있으며 성능이 우수합니다. 이미 좋은 해결책을 찾은 것처럼 들립니다 ...

경로 찾기 솔루션은 현재 솔루션보다 복잡 할 가능성이 높으므로 디버깅이 필요할 수 있습니다. 아마 느려질 것입니다.

IMO가 고장 나지 않았다면 고치지 마십시오.

편집하다

IMO, 미로가 고정되면 현재 솔루션 훌륭하고 우아한 코드입니다. "좋은"또는 "우아한"을 "영리한"과 동일시하는 실수를하지 마십시오. 간단한 코드는 "좋고"우아 할 수 있습니다.

구성 가능한 미로 레벨이있는 ​​경우 처음 미로를 구성 할 때 경로 찾기 만 수행하면됩니다. 가장 간단한 방법은 미로 디자이너가 직접 할 수 있도록하는 것입니다. 나는 당신이 bazillion 미로를 가지고 있거나 사용자가 디자인 할 수 있다면 이것을 자동화하는 것을 귀찮게 할 것입니다.

(외부 : 경로가 수동으로 구성되면 미로 디자이너는 차선의 경로를 사용하여 레벨을 더 흥미롭게 만들 수 있습니다 ...)


예, 작동합니다. 그러나 코드뿐만 아니라 좋은 코드를 작성하고 싶습니다. 또한 추가로 내 질문에 마지막 문장을 추가 했으므로 가능하면 알고리즘은 미로뿐만 아니라 여러 미로도 있어야합니다.
RoflcoptrException

미로도 생성 될 수 있습니다 (저는 멋진 팩맨 미로를 생성하는 알고리즘이 있습니다). 약간의 자동화가 필요합니다
Erich Kitzmueller

"... 또는 사용자가 디자인 할 수 있습니다." 이 경우, 당신은 bazillion 미로를 가지고 있습니다.
phuzion

@ phuzion-알고 있습니다. 그러나 두 경우에는 차이가 있습니다. Bazzilion 미로를 만드는 것이 OP라면, 직접 라우팅을 만들어야하는 것은 불편합니다. 최종 사용자 인 경우 ... OP는 문서를 작성하고 최종 사용자 미로의 끝없는 문제 해결, 비우호적 인 방법에 대한 끝없는 불만 등을 수행해야 함을 의미합니다. 다시 말해서 자동 경로 생성을 구현 하는 이유다릅니다 .
Stephen C

14

원래 팩맨에서 유령은 자신의 "냄새"에 의해 노란 알약 먹는 사람을 발견했습니다. 그는지도에 흔적을 남길 것입니다. 유령은 냄새를 발견 할 때까지 무작위로 돌아 다니다가 냄새 경로를 따라 가서 플레이어. 팩맨이 움직일 때마다 "냄새 값"이 1 씩 감소합니다.

이제 전체 과정을 뒤집는 간단한 방법은지도 중앙에 가장 높은 지점을 가진 "유령 냄새의 피라미드"를 갖는 것입니다. 그러면 유령은이 냄새의 방향으로 움직입니다.


나는이 접근법이 정말 마음에
들어서

5
이것은 정확하지 않습니다. 그들이 모두이 알고리즘을 따랐다면 결국 그에게 단일 파일을 쫓게됩니다. 각 유령의 행동은 다릅니다. Wikipedia 기사에서 자세한 정보를 찾을 수 있습니다.
분배기

5

팩맨을 쫓는 데 필요한 논리가 이미 있다고 가정하면 왜 재사용하지 않습니까? 대상을 변경하십시오. 동일한 논리를 사용하여 완전히 새로운 루틴을 작성하는 것보다 훨씬 적은 작업 인 것 같습니다.


그래, 난 이미 구현 된 팩맨을 쫓는 논리를 가지고 있지만, 나는 또한 그것에 만족하지 않는다;)
RoflcoptrException

내 경험상 (나는 재미를 위해 팩맨 버전을 쓰는 것을 좋아합니다), 그렇게하면 오랫동안 구멍 밖에 눈이 붙어있을 수 있습니다. 체 이싱 알고리즘은 일반적으로 "팩맨이 북쪽에 있으면 북쪽으로 가십시오"라는 선을 따르지만 미로는 눈이 먼저 남쪽으로 가야하는 "트랩"을 포함 할 수 있기 때문입니다. 팩맨이 움직이면 유령은 조만간 탈출하지만 구멍은 고정 된 목표입니다. (참고 : 생성 된 미로에 대해 이야기하고 있습니다)
Erich Kitzmueller


3

각 정사각형은 중심까지의 거리 값을 가지고 있습니까? 이 방법으로 주어진 각 사각형에 대해 가능한 모든 방향으로 인접한 이웃 사각형의 값을 얻을 수 있습니다. 가장 낮은 값을 가진 사각형을 선택하고 해당 사각형으로 이동하십시오.

사용 가능한 알고리즘을 사용하여 값을 미리 계산합니다.


나는 이것을 제안하려고했다. '몬스터 홀'에서 시작하는 외곽의 홍수 채우기. 나는 당신의 대답이 사진에서 도움이 될 것이라고 생각합니다.
AjahnCharles 4

3

이것이 실제로 어떻게 작동했는지 찾을 수있는 최고의 출처였습니다.

http://gameai.com/wiki/index.php?title=Pac-Man#Respawn 유령이 죽으면 눈에 보이지 않는 눈이 시작 위치로 돌아갑니다. 이것은 유령의 대상 타일을 해당 위치로 설정하여 간단히 수행 할 수 있습니다. 탐색에는 동일한 규칙이 사용됩니다.

실제로 의미가 있습니다. 어쩌면 세계에서 가장 효율적이지는 않지만 다른 주 또는 목표를 변경하는 선을 따라 다른 것에 대해 걱정할 필요가없는 아주 좋은 방법 일 수 있습니다.

참고 사항 : 저는 그 팩맨 프로그래머가 기본적으로 메모리가 매우 작은 매우 작은 공간에서 전체 메시지 시스템을 만드는 것이 얼마나 멋진 지 알지 못했습니다.


2

나는 당신의 해결책이 그 문제보다 더 간단하다고 생각합니다. 유령의 눈이 벽을 통과 할 수있는 새로운 버전을보다 "현실적인"것으로 만드는 것입니다 =)


2
더욱 사실감을 더하기 위해 유령들 자신이 벽을 통과 할 수있게하십시오. D
Thomas Eding

3
그것들은 유령의 불투명 한 벽이지만 2 차 유령 (고스트의 유령)은 더 투명합니다. (기능에 버그가 변형 된 많은 사용자 매뉴얼을 찾을 수 있습니다)
Hernán Eche

1
"2 차 유령"에 +1 – 아, 유령의 파생물은 반드시 벽과 같은 단순한 1 차 객체를 초월해야합니다 ... :)
Assad Ebrahim

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

아이디어는 너비가 가장 넓은 검색이므로 인접한 새로운 사각형이 나타날 때마다 가장 좋은 경로는 p입니다. 내가 믿는 O (N)입니다.


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

짧은 대답, 잘되지 않습니다. :) 팩맨 미로를 변경하면 눈이 반드시 다시 오는 것은 아닙니다. 떠 다니는 일부 해킹에는 그 문제가 있습니다. 따라서 협동 미로가 있어야합니다.


2

귀신이 홀에서 팩맨으로 향한 길을 저장한다고 제안합니다. 유령이 죽 자마자, 그는이 저장된 길을 반대 방향으로 따라갈 수 있습니다.


2
아마 그 길은 아마 너무 길 것입니다
Ahmad Y. Saleh

노드를 다시 방문 할 때마다 히스토리에서 루프를 제거 할 수 있습니다. 그것은 좀 더 직접적으로 만들 것입니다. 항상 동일한 직접 경로를 따르는 것보다 더 흥미로울 수 있지만, 종종 거의 바보 같은 고리 (예 : 정사각형의 3면)가 포함됩니다.
AjahnCharles

1

팩맨 경로가 무작위가 아님을 아는 것 (즉, 각 특정 레벨 0-255, 더러워진, 깜박임, 핑키 및 클라이드는 해당 레벨에 대해 동일한 경로로 작동 함).

나는 이것을 가지고 나서 전체 미로를 감싸는 마스터 경로가 팩맨이 귀신을 먹었을 때의 위치에 계류하는 "반환 경로"로 추측된다.


1

팩맨의 유령은 목표가 달성 될 때까지 X 또는 Y에서 먼저 일치하려고하는 관점에서 다소 예측 가능한 패턴을 따릅니다. 나는 항상 눈이 길을 찾는 것과 동일하다고 생각했습니다.


1
  1. 게임이 시작되기 전에 맵에 노드 (교차로)를 저장하십시오
  2. 몬스터가 죽으면 포인트 (좌표)를 가져 와서 노드 목록에서 가장 가까운 노드를 찾습니다
  3. 해당 노드에서 구멍까지의 모든 경로를 계산하십시오.
  4. 최단 경로를 길이로 가져 가십시오
  5. 점과 가장 가까운 노드 사이의 공간 길이를 추가합니다
  6. 경로를 그리고 이동

즐겨!


1

내 접근 방식은 약간의 메모리 집약적이지만 (Pacman 시대의 관점에서) 한 번만 계산하면되며 모든 레벨 디자인 (점프 포함)에서 작동합니다.

한 번 레이블 노드

레벨을 처음로드 할 때는 모든 몬스터 레이어 노드 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

내 팩맨 게임을 shortest multiple path home위해 나는 내가 제공하는 미로에 대해 약간의 " "알고리즘을 만들었다 . 또한 터널을 가로 질러 작동합니다.

레벨이로드되면 모든 항목 path home data in every crossroad이 비어 있고 (기본값) 유령이 미로를 탐색하기 시작 crossroad path home information하면 "새"교차로가 나갈 때마다 또는 알려진 교차로에서 다시 다른 경로에서 넘어 질 때마다 계속 업데이트됩니다.


-2

원래 팩맨은 길 찾기 나 멋진 AI를 사용하지 않았습니다. 게이머는 실제보다 깊이가 더 크다고 믿었지만 실제로는 무작위였습니다. 게임 / Ian Millington, John Funge의 인공 지능에 명시된 바와 같이.

그것이 사실인지 확실하지 않지만 나에게는 많은 의미가 있습니다. 솔직히, 나는 사람들이 말하는 이러한 행동을 보지 못했습니다. ex의 빨간색 / 깜박임은 플레이어가 항상 말한 것처럼 플레이어를 따르지 않습니다. 의도적으로 플레이어를 지속적으로 따르는 사람은 없습니다. 그들이 당신을 따를 확률은 나에게 무작위로 보입니다. 그리고 좁은 공간에서 적 4 명과 회전 옵션이 제한되어있어 추격 당할 확률이 매우 높을 때 무작위로 행동하는 것을 보는 것은 매우 유혹적입니다. 적어도 초기 구현에서 게임은 매우 간단했습니다. 책을 확인하십시오. 첫 장 중 하나에 있습니다.


예, AI를 사용했습니다. 그가 추적 모드에서의 (수시로에서 전환) 할 때 그리고 네 블링키는 팩맨을 다음과 그것의 AI 모든 권리 그래서
장 - 프랑수아 파브르
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.