ローグライク迷路生成のための最長経路アルゴリズム


10

次のように、部屋で構成されたシンプルなグリッドベースのマップがあります(A =入り口、B =出口):

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

そして、プレイヤーが出口を見つける前にマップの大部分を探索しなければならないような方法で、部屋の間にドアのパスを作成するための適切なアルゴリズムを作成しようとするのに行き詰まっています。

つまり、AからBへの可能な最長のパスを見つけようとしています。

(この問題は非循環グラフでも解決できることは承知していますが、この場合は循環が発生する可能性があります。)

編集:塗りつぶしを使用して部屋が接続され、出口が入口から最も遠い部屋として選択されている別の例:

   0 1 2 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での騎士のジャンプやテレポーテーションのような奇妙な動きのパターンを持っている場合でも、出口を見つけるために、より多くの部屋を探索する必要があります。

静的に出口を生成する必要がある場合は、仮想キャラクターで同じアイデアを使用できます。キャラクターの位置から始まり、各反復でセルを1回移動する塗りつぶしを想像してください。埋められる最後の部屋は、出口が属する部屋です(実際、最後に埋められるセルは、プレイヤーから最も遠いセルです)。ただし、この場合、プレーヤーは出口についてより多くの情報を持っています。左側にいる場合、右側にある可能性が高く、テレポートできる場合、実際には通常のランダムウォークよりも速く到達できる可能性があります。

最後に、出口がマップの反対側にプレイヤーキャラクターから出現するローグライクを完成させ、ランダムにさまよった。ダンジョン内のいくつかのアイテムは、空腹が速くなることを犠牲にして、それを地図上に表示しました。私は何も分析しませんでしたが、それを見つけるためにマップをさらに探索する必要があることは間違いなく感じられ、レベルに独特の感覚が与えられました。


動的な生成は、プレイヤーが気付かない限り、かなり良い考えのように思えます。さもなければ、彼らはかなりのだまされたと思うでしょう。でも、私は塗りつぶしのアイデアが大好きです。
ユーザーが

2
まあ、あなたの提案全体はある意味でプレイヤーをだますのです。世界モデルを必要としないように数学を洗練させたことで私を責めないでください。;)しかし、デザイントリックを使用して口当たりを良くすることができます。たとえば、出口はアプリオリに配置されますが、それを使用するために必要なキーは、私が説明した方法で生成されるか、Xを探索した後にのみ出現するモンスターに配置されます部屋/ Xモンスターを殺す、またはドアを開くには、Xスイッチを切り替える必要があります(各部屋に1つずつなど)

フラッドフィルアプローチを試しました。すべての部屋を接続して短いブランチを生成するのはうまくいきますが、出口が最後にアクセスしたノード(または私の実装では最も遠いノード)であっても、実際には出口への最長パスを生成しません。(私の質問に追加された例)
ユーザーが

でも、私はキー/スイッチベースの迷路が大好きです。ツリーでこのようなことを実装する方が簡単に思えます。2つのブランチがある場合、どのブランチが出口につながるかを検出し、それをブロックし、キーを他のブランチに置くことができるからです。
ユーザーが

しかし、私はそれが「AからBへ」のパスファインディング問題であると考えるのが間違っていたことを認めます。出口ではなく、アルゴリズムの結果として出口を見つける方が理にかなっていると思います。
ユーザーが

6

可能な代替策は、(サイクルを排除するために)Prim / Kruskalを使用して(最大?)スパニングツリーを作成し、スパニングツリーに従来の最長パスアルゴリズムを適用することです。

ただし、スパニングツリーアルゴリズムは行き止まりのブランチを作成する傾向があり、プレーヤーに常にバックトラックを強いるのではないかと心配しています。

編集:クラスカルベースのアルゴリズムを使用し、最も長いブランチの最後に出口を配置した結果:

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

1
私もプリムを提案するつもりでした:-)、+1、バックトラックも多くのゲームの重要な部分だと思います...ディアブロ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
}

パスに沿ってドアをランダムに削除します。そうしないと、出口にドアが1つあり、最初に何トンものドアができてしまいます。

これはO(n^2)大きな地図にはあまり向かないと思います。


原則として非常にエレガントなソリューションです。次回は、このようなことを考えてから、複雑な手法に取り掛かる必要があります。
ユーザーが

まあ、エレガントかもしれませんが、それはプロセッサの独占になるでしょう。O(n ^ 2)は、大きなマップでは適切にスケーリングされません。
Stephen Furlani


1

あなたはすでに素晴らしい答えを持っていると思いますが、これが問題に対する私の理論的解決策の0.02ドルです。

必要なのは最長経路ではなく、最短経路です。部屋への最短経路を考慮している場合、最も離れた部屋が必要です。これはおそらく混乱するように思えますが、計算するのは非常に簡単です。

  1. スターティングルームから開始します。隣人のそれぞれに1をマークします。それらは開始部屋から1の距離にあります。
  2. 1とマークされた各部屋について、マークされていない隣の部屋をそれぞれ訪問し、それらに2とマークを付けます。
  3. すべての部屋をカバーするまで続けます。最大数の部屋は、最初から最も遠くにあります。

実際に最長の経路を計算する(たとえば、10室の場合はあまり長くかかりません)と、プレーヤーにその最長の経路をたどることができないため、機能しません。したがって、入口と出口を互いに最も離れた2つの部屋に置くことが最善の策です。これを見つけるには、ランダムな部屋から最も遠い部屋を計算します。次に、その部屋から、最も遠い部屋を見つけます。これをグラフの直径を見つけるといいます。Googleで検索してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.