手続き…ルームジェネレーターのある家


74

私は、ダンジョンを手続き的に生成することに関するいくつかのアルゴリズムと記事を見てきました。問題は、部屋のある家を作ろうとしているのに、部屋が私の要件に合わないようだということです。

たとえば、ダンジョンには廊下があり、家にはホールがあります。最初は同じように見えるかもしれませんが、ホールは部屋ではないエリアにすぎませんが、廊下はあるエリアを別のエリアに接続するように特別に設計されています。

家とのもう1つの重要な違いは、特定の幅と高さがあることです。また、ダンジョンでは空間が空いているのに対して、部屋全体やホールで物全体を埋める必要があります。

家のホールは、ダンジョンの廊下(他の部屋に行く)とダンジョンの空きスペース(コードで明示的に定義されていない)の間にあるものだと思います。

具体的には、要件は次のとおりです。


  • すぐに壁やドアを作成できない定義済みの部屋のセットがあります。
  • 部屋は回転することはできますが、サイズを変更
    することはできません。部屋の定義済みのセットがあるため、サイズを変更することはできません。
  • 家の寸法は設定されており、部屋(またはホール)で完全
    に埋める必要があります。つまり、空きスペースがないことを確認して、利用可能な部屋で14x20の家を埋めたいと思います。

これをもう少し明確にするいくつかの画像を次に示します。

典型的なダンジョンジェネレーター 廊下のないダンジョン ハウスジェネレーター結果

ご覧のとおり、家の中では、「空のスペース」はまだ歩きやすく、ある部屋から別の部屋に移動できます。

したがって、これらすべてを言ったとしても、家は廊下のある非常にぎっしり詰まったダンジョンです。または、ダンジョンよりも簡単なものです。たぶんそこに何かがあり、何を検索すればよいかわからないので見つけられませんでした。

これがあなたの助けが欲しいところですこのアルゴリズムを設計する方法についてのポインタを教えてもらえますか?どのステップを踏むかについての考えはありますか?ダンジョンジェネレーターを作成した場合、要件に合わせてどのように変更しますか?好きなだけ具体的または汎用的にすることができます。本当にあなたの頭脳を探しています。


2
奇妙な推奨事項:クリストファー・アレクサンダーの著書The Timeless Way Of Building and A Pattern Languageをチェックすることを強くお勧めします。これは、(ソフトウェア)パターンの概念の元の基礎を形成した建築書です。それらは本質的に、トップダウンの手続き型構築方法に変えることができる建物と生活空間のための明示的な言語を記述しています。
スティーブンスタドニッキー

個人的には、エガルギアスの答えのようなアルゴリズムを作ろうとします。まず、部屋のプレースホルダー(さまざまな数の部屋で埋めることができる大きな領域。各部屋のプレースホルダーには、特定の(または下限を持つランダムな)サイズのギャップが必要です。「ギャップ」スペースは、家の中ではなく、部屋にある廊下すなわちスペースを考慮され、部屋のプレースホルダは、例えば「いいえ廊下でダンジョン」あなたに似たランダムなサイズの部屋で満たされるでしょう。
ベンジャミン危険ジョンソン

@pekソリューションの答えを作成してください。質問には入れないでください。
マイケルハウス

@ Byte56完了。明確にするために、他の人が提案したことだけをしたので、信用を得たくなかったので、私はそれをしました。しかし、なぜそれがサイトのフォーマットにとって理想的ではないのか理解しているので、答えを追加しました。
ペック

ありがとう@pek。クレジットを取得することについて心配する必要はありません。それは当然であり、サイトにアクセスする人がソリューションを見るのに役立ちます(そして、予想される場所で見るのが最善です)。
マイケルハウス

回答:


50

これは、バイナリまたはターナリスペースパーティションを使用する場合に適していると思います。

最初のパスでは、家のスペースをホールと{部屋のブロック}に分割します。次の大きなチャンクを取得し、{hall and chunk}または{2 chunks and hall betweenそれらの間に分割します}。すべてのステップで、スライス方向を90度回転します。{大きなチャンクが残っていない}または{ホールの総面積が制限に達した}ときに停止します。

2番目のパスで、残りのチャンクを部屋に分割します。次の大きなチャンクを取得して分割します。いくつかのそれほど大きくないチャンクをランダムに分割することをスキップして、いくつかの大きな部屋を確保します。

ホールがはるかに古いホールに面している場合は、そこに壁(またはドアのある壁)を配置します。

部屋をホールと直接接続するか、既に接続されている他の部屋を介して接続します。

たとえば、手動で作成した結果またはC ++に似た部分的に完了した擬似コードのいずれかを確認できます。最終ショット:

最終ショット


それが私の研究の結果であり、空間分割になりました。コードを使用した例は、非常に良いスタートを切ってくれました。現在、アルゴリズムを読んでいます。ただし、1つの質問:私の要件の1つは、部屋が事前に定義されていることです(つまり、ドアが2x2、ドアが2x1、ドアが3x2x2ではありません)。 。パーティションを作成している間、自分の制限に留意する必要があると思います。私がこれについてどうするかについての提案はありますか?いずれにせよ、あなたの答えと努力に感謝します!
ペック

@pek単なる人間がこの問題の学術的な解決策を見つけることができるかどうかはわかりません。チャンクスプリッターとボックススプリッターに追加の条件を設定し、すべての条件が満たされるレベルが見つかるまでレベルを生成およびドロップしてみてください。
雨の影13年

ええ、私は何かが欠けていることを望んでいました。私の最初のアプローチは、A *を使用して特定のスペースに部屋を収める方法を見つけることでしたが、ホールのロジックが欠けていました。今、私はBSPを使用してホールを配置し、ブロックにA *を使用できると考えています。私が最も心配しているのは、それがあまりにも高価であり、必ずしも結果を生成しないかもしれないということです。しかし、最初にこれをテストする必要があります。たぶんそれは悪くないでしょうか?
ペック

2
@pekまだ興味があれば、何か役に立つものが見つかりました。これも、グーグルも見てくださいL-system
雨の影13年

24

廊下に囲まれた長方形の部屋に希望のデザインをまとめているという事実を活用できます。それを念頭に置いて、私はこれをします:

  1. 部屋の廊下と「大きなスペース」を設計する
  2. 各「大きなスペース」に部屋を埋める

2ステップ

大きなスペースを部屋で埋めるには、国境の部屋から始めると簡単にできます。たとえば、廊下に面した部屋にはその壁にドアを置くことができますが、「外壁」に面した部屋はできません(おそらくウィンドウがあります)。大きな部屋の「内側」にある部屋には、少なくとも1つの入り口が必要です。


15

だから、ここに私がこの問題を解決した方法があります。しかし、最初に、@ Shadows In Rainと@egarciaの両方の回答に感謝します。彼らは私にいくつかの結果を得るのに役立つ良い方向性を与えてくれました。

Shadows In Rainのスペースパーティショニングを使用して基本的な家を生成し、エガルシアのアドバイスに従って部屋に部屋を埋めました。

コードの90%がShadowsによって行われたため、スペースの分割は非常に簡単でした。「部屋を埋める」部分はもう少し挑戦的でした。A *を使用して部屋を適切に配置する擬似AI計画システムを使用することにしました。単なるA *の代わりに計画を使用することの良い点は、前提条件が検索スペースを大幅に削減するのに役立つことです。

結果のスクリーンショットは次のとおりです。

フロアプラン生成フェーズ フロアプラン生成フェーズ

部屋配置段階 部屋配置段階

コネクティングドアで!
コネクティングドアで!


11

Dahl&Rinde は、スケルトン&リージョンアプローチを使用して建物の内部を部屋と廊下で埋める屋内環境の手続き生成に関する論文を持っています。このペーパーには、プロトタイプのクラス図が含まれています。前述のA Pattern Languageを含む参考文献にもいくつかの参考文献があります。

彼らの仕事は、次の単純化された仮定に基づいて設計されました。

  • アパートの建物のみを扱う
  • 分割レベルなし
  • 建物(エンベロープ)の形状を制限するには、多角形でなければなりません
  • 封筒に穴がない
  • 類似または線形に変化するエンベロープの厚さ(つまり、砂時計の形状なし)
  • 廊下が必要な建物のみを扱う

プロセスの概要は次のとおりです。

  • エンベロープのスケルトンを見つけます。エンベロープは、エンベロープからの距離、ドアまたは階段への近接度、および以前に配置されたコリドーへの近接度に基づいて、スケルトンに沿って配置されます。
  • 次に、残りの非廊下空間は、それぞれが単一の連続した境界を持つ最大接続エリアに分割されます。場合によっては、これには壁の挿入が必要になります。
  • これらの領域は、アパートメントに分割され、アパートメントごとに少なくとも1つのウィンドウを割り当てようとします。場合によっては、小さな区画が合併して、過度に小さなアパートを回避します。ウィンドウのない領域は単に無視されます。
  • 最後に、次のように、重み付きボロノイのような図を基礎として使用して、アパートメントを部屋に分割します。

    • シードの重みは、部屋のサイズに影響を与えるために使用されます。種子はドアや窓に追加されます。通常、目的の部屋ごとに1つずつ、追加のシードが追加されます。明示的には述べられていませんが、種子はアパートの外壁に沿って配置されているように見えます。
    • 最遠点から始めて、与えられたシードと他のすべての点との間の線が計算され、その後、終点のそれぞれの重みに関連する距離を二等分します(AとBの重みが1と4の場合、二分点はAからBへの道の1/4。次に、外壁とともに二等分線のコレクションが種子のセルを形成します。
    • 次に、S-Space壁スケルトン(Peponis et al 1997による)は、隣接する外壁フィーチャ(窓またはドア)の中間点から垂直に始まる線で領域を分割することによって作成されます。
    • 最後に、「Voronoiセル壁に対応し、可能な限り対応する」Sスペーススケルトンから壁が選択されます。

3
写真を含めることはできますか?それは素晴らしいことです。私は紙をざっと読みましたが、彼らが生成した部屋は建築物のPOVからは良さそうでした。
コンガスボンガス

非常に興味深い方法です。それを取り除ける可能性のあるアイデアについては、自分でもっと詳しく調べなければなりません。
Draco18s

私は仕事からリラックスするためにここに来ました...驚きの研究テーマが出てきました。私は自分の研究に基づいて答えを書くのが面倒です(私はまだアルゴリズムの必要最小限の部分しか設計していないので、とにかくそれは価値がありません)または問題へのDanil Nagyのアプローチを説明します。autodeskresearch.com/publications/...
フェリペ・グティエレス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.