악성 유사 미로 생성을위한 최장 경로 알고리즘


10

다음과 같이 방으로 구성된 간단한 그리드 기반 맵이 있습니다 (A = entrance, B = exit) :

   012 3
  #########
0 # B # #####
  #########
1 # ### #
  #########
2 # # #
  # # #
삼 # # #
  #########
4 # ### #
  #########
5 ### A #
  ### #
6 ### #
  #########

그리고 플레이어가 출구를 찾기 전에 대부분의지도를 탐색해야하는 방식으로 방 사이에 문 경로를 만들기 위해 적절한 알고리즘을 만들려고 노력하고 있습니다.

즉, A에서 B까지 가능한 가장 긴 경로 를 찾으려고합니다 .

(비순환 그래프에서는이 문제를 해결할 수 있지만이 경우주기가있을 수 있음을 알고 있습니다.)

편집 : 방이 범람을 사용하여 연결되고 출구가 입구에서 가장 먼 방으로 선택되는 또 다른 예 :

   012 3
  #########
0 # B # #
  # #-#####
1 # | # #
  ### # #
2 ### # #
  ###-#-###
3 # | ###
  #-#######
4 #A | #
  # # #
5 # # #
  # # #
6 # # #
  #########

출구까지의 경로는 가능한 가장 긴 경로가 아닙니다.


플레이어가 가능한 한 가장 긴 경로를 사용하도록 강요하면 실제로 복잡한 척하는 직선 경로를 만드는 것입니다. 이것은 나쁘다.
o0 '.

나쁘지는 않지만 (예를 들어 레일 슈터 장르의 기초), 당신은 당신이하고 있다는 것을 알고 나머지 게임과 잘 작동하도록 설계해야합니다.

레벨이 대부분 선형 일 때 게임의 속도를 제어하는 ​​것이 더 쉽습니다. 예를 들어, 특히 어려운 몬스터 룸 뒤에 복구 실을 추가 할 수 있습니다. 주요 경로가 없다면 도전과 보상의 분배는 무작위입니다.
사용자

답변:


11

나는 당신이 이것에 대해 잘못된 길을 가고 있다고 생각합니다. 주기가있는 그래프의 최대 경로는주기가 시작과 끝 사이에있는 경우 무한하므로 기술적으로 정의되지 않습니다. 최대 경로의 정의를 확장 / 제한 할 수있는 영리한 방법이있을 수 있지만 이것이 최선의 방법이라고 생각하지 않습니다.

실제 긴 경로를 모델링하려고하지 않습니다 (예 :지도에서 가능한 한 많은 영역을 탐색하려는 로봇). 당신은 플레이어가 많은 방을 탐험하도록 노력하고 있습니다.

따라서 플레이어가 지금까지 탐색 한지도의 비율에 비례하여 출구를 찾을 수있는 기회를 만드십시오 . 레벨에 X 방이 있고 플레이어 캐릭터가 Y를 탐험했다고 가정 해 봅시다. 다음에 캐릭터가 방에 들어올 때 출구를 f (Y, X) 확률로 배치하십시오. f의 사소한 예는 (Y * Y) / (X * X) 일 수 있습니다. 예를 들어 10 개의 객실의 경우 마지막 방에서 100 % 확률로 마지막 방에서 나올 확률이 81 %이며 마지막 방 옆으로 올 확률은- 첫 번째 방에있을 확률 1 %

당신은 게임을 올바르게 느끼고 싶을 때 방정식을 조정할 수 있으며, 심지어 플레이어에게 좀 더 생성 할 수있는 능력을 줄 수도 있습니다. 중요한 부분은 캐릭터가 실제로 방에 들어갈 때까지 출구를 생성하지 않는 것입니다. 이 방법은 또한 던전 생성 알고리즘에 대한 플레이어 지식에 영향을받지 않습니다. 플레이어가 기사가 NetHack에서 점프하거나 순간 이동하는 것과 같은 이상한 움직임 패턴을 가지고 있어도 출구를 찾기 위해 더 많은 방을 탐색해야합니다.

출구를 정적으로 생성 해야하는 경우 가상 캐릭터에 동일한 아이디어를 사용할 수 있습니다. 캐릭터의 위치에서 시작하여 홍수가 반복 될 때마다 한 번 이동하는 플러드 필을 상상해보십시오. 채워질 마지막 방은 출구가 속한 방입니다 (실제로 채워질 마지막 셀은 플레이어와 가장 먼 셀입니다). 그러나이 경우 플레이어는 출구에 대한 자세한 정보를 얻습니다. 왼쪽에 있으면 오른쪽에있을 가능성이 높으며 순간 이동이 가능하면 실제로 정상적인 무작위 보행보다 더 빨리 갈 수 있습니다.

마지막으로, 출구가 플레이어 캐릭터에서 맵의 다른쪽에 스폰되는 곳에서 불량한 것을 끝내고 무작위로 방황했습니다. 던전의 일부 아이템은 배가 고파지면서 맵에 표시되었습니다. 나는 어떤 분석도하지 않았지만,지도를 찾기 위해 더 많은지도를 탐색해야한다고 느꼈으 며, 레벨에 독특한 느낌을주었습니다.


플레이어가 눈치 채지 않는 한 동적 생성은 꽤 좋은 생각처럼 보입니다. 그렇지 않으면 나는 그들이 매우 속임수라고 생각합니다. 그래도 범람 아이디어를 좋아합니다.
사용자

2
글쎄, 당신의 전체 제안은 어떤 의미에서 플레이어를 속이는 것입니다. 월드 모델을 요구하지 않기 위해 수학을 구체화했다고 탓하지 마십시오. ;) 그러나 디자인 트릭을 사용하여 더 맛있게 만들 수 있습니다. 예를 들어, 출구는 우선 순위가 있지만, 사용하는 키는 설명 된 방법으로 생성되거나 X를 탐색 한 후에 만 ​​생성되는 몬스터에 배치됩니다 X 몬스터를 죽이거나 문을 열려면 X 스위치를 뒤집어 야합니다. 각 룸마다 하나씩 전환해야합니다.

플러드 필 접근법을 시도했습니다. 그것은 모든 방을 연결하는 좋은 일을하고 짧은 지점을 생성하지만 출구가 마지막으로 방문 한 노드 (또는 구현에서 가장 먼 노드) 일지라도 출구에 가능한 가장 긴 경로를 생성하지는 않습니다. (내 질문에 추가 된 예)
사용자

그래도 키 / 스위치 기반 미로입니다. 나무로 그런 종류의 것을 구현하는 것이 더 쉬워 보입니다. 두 개의 분기가 있으면 출구로 이어지는 분기를 감지하고 차단하고 다른 분기에 키를 넣을 수 있기 때문입니다.
사용자가 찾을 수 없음 :

그러나 나는 그것이 "A to B"길 찾기 문제라고 생각하는 데 잘못되었다는 것을 인정한다. 목표가 아닌 알고리즘의 결과로 출구를 찾는 것이 더 합리적이라는 것을 알고 있습니다.
사용자를 찾을 수 없습니다

6

가능한 대안은 Prim / Kruskal을 사용하여 (사이클을 제거하기 위해) (최대?) 스패닝 트리를 생성하고 스패닝 트리에서 가장 긴 경로 알고리즘을 적용하는 것입니다.

그러나 스패닝 트리 알고리즘이 막 다른 가지를 생성하여 플레이어가 지속적으로 역 추적하는 경향이 걱정됩니다.

편집 : Kruskal 기반 알고리즘을 사용하고 가장 긴 지점 끝에 출구를 배치 한 결과 :

   012 3
  #########
0 #A | #
  # #####-#
1 # # #
  ### #
2 ### #
  ### #
삼 ### #
  ###-#####
4 # | #
  #-#####-#
5 # ### #
  #-#######
6 # # B #
  # #-#
7 # | #
  #########

1
나도 Primm을 제안하려고 했어요 :-), +1, backtrack이 많은 게임에서 중요한 부분이라고 생각합니다. 디아블로 2를 확인하십시오.
Mr.Gando

2

바이올린과 함께 할 것이 있습니다.

Connect each room with a door to another room.
N = 0.75*TotalNumberOfRooms
Until (pathSize > N) {
  Use A* pathing to get a path from A to B. (G being size of room, or # of monsters)
  if (pathSize < N) remove a connection/door
  if (noPath) choose a different door/connection
  if (room.doors < 1) choose a different door/connection
}

나는 길을 따라 무작위로 문을 제거했다.

O(n^2)큰지도 에는 그렇게 좋지 않다고 생각 합니다.


원칙적으로 매우 우아한 솔루션입니다. 다음에는 복잡한 기술을 사용하기 전에 이와 같은 것을 생각해야합니다.
사용자

글쎄, 아마도 어쩌면 프로세서 호그가 될 것입니다. 큰지도에서는 ​​O (n ^ 2)가 잘 맞지 않습니다.
Stephen Furlani


1

나는 당신이 이미 큰 대답을 가지고 있다고 생각하지만, 여기에 문제에 대한 나의 이론적 해결책의 $ 0.02가 있습니다.

원하는 것은 가장 긴 경로가 아니라 가장 짧은 경로입니다. 방으로가는 가장 짧은 경로를 고려할 때 가장 먼 방을 원합니다. 혼란 스러울 것 같지만 계산하기가 매우 쉽습니다.

  1. 시작 실에서 시작하십시오. 각각의 이웃을 표시하십시오. 그들은 시작 실에서 1 거리 떨어져 있습니다.
  2. 1로 표시된 각 방에 대해, 표시되지 않은 각 이웃을 방문하여 2를 표시하십시오. 그들은 시작에서 2 거리 떨어져 있습니다.
  3. 모든 방을 덮을 때까지 계속하십시오. 최대 수를 가진 방은 시작에서 가장 먼 곳입니다.

실제로 가장 긴 경로를 계산하면 (10 개 방에 너무 오래 걸리지 않음) 플레이어가 가장 긴 경로를 가져갈 수 없기 때문에 작동하지 않습니다. 따라서 가장 멀리 떨어진 두 개의 방에 출입을하는 것이 가장 좋습니다. 이를 찾으려면 임의의 방에서 가장 먼 방을 계산하십시오. 그런 다음 그 방에서 가장 먼 방을 찾으십시오. 이것을 그래프의 직경을 찾는 것입니다 .Google에 알려주십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.