Procedurale ... casa con generatore di stanze


74

Ho esaminato alcuni algoritmi e articoli sulla generazione procedurale di un dungeon. Il problema è che sto cercando di generare una casa con stanze e non sembrano adattarsi alle mie esigenze.

Per uno, i sotterranei hanno corridoi, dove le case hanno sale. E mentre inizialmente potrebbero sembrare uguali, una sala non è altro che l'area che non è una stanza, mentre un corridoio è progettato specificamente per collegare un'area all'altra.

Un'altra differenza importante con una casa è che hai una larghezza e un'altezza specifiche e devi riempire l'intera cosa con stanze e sale, mentre con una prigione c'è spazio vuoto.

Penso che le sale di una casa siano qualcosa tra un corridoio sotterraneo (ti porta in altre stanze) e uno spazio vuoto nel sotterraneo (non è esplicitamente definito nel codice).

Più specificamente, i requisiti sono:

  • C'è una serie di stanze predefinite
    che non posso creare muri e porte al volo.
  • Le stanze possono essere ruotate ma non ridimensionate
    Ancora una volta, poiché ho un set predefinito di stanze, posso solo ruotarle, non ridimensionarle.
  • Le dimensioni della casa sono impostate e devono essere interamente riempite di stanze (o sale).
    Voglio cioè riempire una casa 14x20 con le stanze disponibili assicurandomi che non vi sia spazio vuoto.

Ecco alcune immagini per renderlo un po 'più chiaro:

Generatore di dungeon tipico Sotterraneo senza corridoi Risultato del generatore di casa

Come puoi vedere, in casa lo "spazio vuoto" è ancora percorribile e ti porta da una stanza all'altra.

Quindi, detto tutto ciò, forse una casa è solo una prigione davvero molto fitta di corridoi. O è qualcosa di più facile di un sotterraneo. Forse c'è qualcosa là fuori e non l'ho trovato perché non so davvero cosa cercare.

È qui che mi piacerebbe il tuo aiuto: potresti darmi indicazioni su come progettare questo algoritmo? Qualche idea su quali passi prenderà? Se hai creato un generatore di dungeon, come lo modificheresti per soddisfare le mie esigenze? Puoi essere specifico o generico come desideri. Sto cercando di scegliere il tuo cervello, davvero.


2
Una strana raccomandazione: consiglio vivamente di dare un'occhiata ai libri di Christopher Alexander The Timeless Way Of Building e A Pattern Language , i libri di architettura che hanno costituito la base originale per l'idea di un modello (software); descrivono essenzialmente un linguaggio esplicito per edifici e spazi abitativi che può essere trasformato in un metodo di costruzione procedurale top-down.
Steven Stadnicki,

Personalmente, proverei a creare un algoritmo come la risposta di egarcias. Inizia generando segnaposti di stanza (grandi aree che possono essere riempite con un numero variabile di stanze. Ogni segnaposto di stanza deve avere uno spazio specifico (o casuale con limiti inferiori) tra di loro. Lo spazio "spazio" è quello che sarebbe considerato un corridoio, cioè uno spazio che si trova nella casa ma non in una stanza, e i segnaposti della stanza sarebbero riempiti da stanze di dimensioni casuali simili al tuo esempio di "prigione senza corridoi".
Benjamin Danger Johnson

@pek Crea una risposta per la tua soluzione, non inserirla nella domanda.
MichaelHouse

@ Byte56 Fatto. Per essere chiari, l'ho fatto perché non volevo ottenere credito dal momento che ho fatto solo quello che gli altri mi hanno suggerito. Capisco però perché non sia l'ideale per il formato del sito, quindi ho aggiunto la mia risposta.
pek,

Grazie @pek. Non preoccuparti di ottenere credito, è meritato ed è utile per le persone che vengono sul sito per vedere la soluzione (e vedere dove è meglio è meglio).
MichaelHouse

Risposte:


50

Penso che questo sia un buon caso per usare la partizione spaziale binaria o ternaria.

Al primo passaggio, dividi lo spazio della casa in sale e {blocchi di stanze}. Ottieni il prossimo grosso pezzo, dividerlo in {sala e pezzo} o {2 pezzi e sala tra di loro}. Ad ogni passo, ruotare la direzione di taglio di 90 gradi. Fermati quando {non sono rimasti più grandi pezzi} o {l'area totale della sala ha raggiunto il limite}.

Al secondo passaggio, dividere i pezzi rimanenti in stanze. Ottieni il prossimo grosso pezzo e dividerlo. Evita di dividere casualmente alcuni pezzi non così grandi per avere delle stanze grandi.

Se una sala si affaccia su una sala molto più antica, posiziona il muro (o il muro con la porta) lì.

Collegare le stanze con le sale direttamente o attraverso altre stanze già collegate.

Ad esempio, puoi vedere il mio risultato creato manualmente o C ++ - allo stesso modo pseudo-codice parzialmente fatto . Colpo finale:

Colpo finale


È qui che è nata la mia ricerca, nel partizionamento dello spazio. Il tuo esempio con il codice mi ha dato un ottimo inizio. Attualmente sto leggendo gli algoritmi. Una domanda però: uno dei miei requisiti è che le stanze siano predefinite (cioè ci sono 2x2 stanze con una porta, 1x1 con due porte, ma non 2x2 con tre porte), quindi non posso iniziare il partizionamento e quindi decidere dove collocare le porte . Penso di dover tenere a mente i miei limiti mentre partizionamento. Hai un suggerimento su come procedere? In ogni caso, grazie mille per la risposta e l'impegno!
pek,

@pek Non sono sicuro che un semplice mortale possa trovare una soluzione accademica per questo problema. Puoi provare a impostare condizioni aggiuntive per chunk-splitter e box-splitter, quindi generare e far cadere livelli fino a trovare uno in cui tutte le condizioni possano essere soddisfatte.
Ombre nella pioggia,

sì, speravo che mi mancasse qualcosa. Il mio primo approccio è stato con l'uso di A * per capire come adattare le stanze in un determinato spazio, ma mancava di logica per le sale. Ora sto pensando che posso usare BSP per posizionare le sale e quindi usare A * per i blocchi. La cosa di cui mi preoccupo maggiormente è che potrebbe essere troppo costoso e non sempre produrre un risultato. Ma dovrò provarlo prima. Forse non sarà così male?
pek,

2
@pek Ho trovato qualcosa di utile, se ti interessa ancora. Guarda questo , anche Google L-system.
Shadows In Rain

24

Puoi trarre vantaggio dal fatto che il design desiderato ingombra le stanze in stanze rettangolari circondate da corridoi. Con questo in mente, farei questo:

  1. Progetta i corridoi e i "grandi spazi" per le stanze
  2. Riempi ogni "grande spazio" con le stanze

2 passaggi

Riempire i grandi spazi con le stanze può essere fatto facilmente se si inizia con le stanze ai bordi: hanno vincoli specifici, ad esempio le stanze che si affacciano su un corridoio possono avere una porta su quel muro, ma le stanze che si affacciano sulle "pareti esterne" non possono (potrebbero avere finestre, forse). Le stanze "dentro" i grandi blocchi di stanze avranno bisogno di almeno un ingresso.


15

Quindi, ecco come ho risolto questo problema. Ma prima vorrei ringraziare sia @Shadows In Rain che @egarcia per le loro risposte. Mi hanno dato una buona direzione che mi ha aiutato a ottenere alcuni risultati.

Ho usato il partizionamento spaziale di Shadows In Rain per generare una casa di base e poi ho seguito il consiglio di egarcia di riempire l'area di stanze.

Il partizionamento dello spazio è stato piuttosto semplice in quanto il 90% del codice è stato fatto da Shadows. La parte "riempi le stanze" è stata un po 'più impegnativa. Ho deciso di utilizzare un pseudo sistema di pianificazione AI che utilizza A * per posizionare le stanze in modo appropriato. L'aspetto positivo dell'utilizzo della pianificazione anziché della sola A * è che le condizioni preliminari aiutano a ridurre significativamente lo spazio di ricerca.

Ecco alcuni screenshot con i risultati:

Fase di generazione della planimetria Fase di generazione della planimetria

Fase di posizionamento della stanza Fase di posizionamento della stanza

Ora con porte comunicanti!
Ora con porte comunicanti!


11

Dahl e Rinde hanno pubblicato un documento di tesi sulla generazione procedurale di ambienti interni che utilizza un approccio basato su scheletro e regioni per riempire gli interni degli edifici con stanze e corridoi. Il documento include diagrammi di classe per il loro prototipo. Ci sono anche alcuni buoni riferimenti nella loro bibliografia, incluso il già citato A Pattern Language .

Il loro lavoro è stato progettato attorno alle seguenti ipotesi di semplificazione:

  • occupandosi solo di condomini
  • nessun livello diviso
  • limitare la forma degli edifici (busta) deve essere poligonale
  • nessun foro nella busta
  • spessore della busta simile o variabile in modo lineare (IE senza forme a clessidra)
  • occuparsi solo di edifici che necessitano di corridoi

Ecco una breve panoramica del loro processo:

  • Trova lo scheletro per la busta. I corridoi vengono quindi posizionati lungo lo scheletro in base alla distanza dall'involucro, dalla vicinanza alle porte o alle scale e dalla vicinanza ai corridoi precedentemente posizionati.
  • Successivamente, lo spazio non corridoio rimanente viene suddiviso in aree massime connesse, ognuna con un unico confine continuo. In alcuni casi, ciò richiederà l'inserimento di un muro.
  • Queste regioni vengono quindi divise in appartamenti nel tentativo di allocare almeno una finestra per appartamento. In alcuni casi le divisioni più piccole si uniranno per evitare appartamenti troppo piccoli. Le regioni senza finestre vengono semplicemente ignorate.
  • Infine, gli appartamenti sono divisi in stanze usando un diagramma ponderato simile a Voronoi come base come segue:

    • I pesi dei semi vengono utilizzati per influenzare le dimensioni della stanza. I semi vengono aggiunti a porte e finestre. Vengono aggiunti semi aggiuntivi, generalmente uno per stanza desiderata; anche se non esplicitamente dichiarato, sembra che i semi siano posizionati lungo le pareti esterne dell'appartamento.
    • A partire dal punto più lontano, viene calcolata una linea tra il seme dato e tutti gli altri punti, quindi viene divisa in due una distanza relativa ai rispettivi pesi dei punti finali (ad esempio se A e B avessero pesi di 1 e 4, il punto di sezionamento sarebbe 1/4 della strada da A a B). La raccolta di linee di sezionamento, insieme alla parete esterna, costituisce quindi la cellula per il seme.
    • Successivamente, viene creato uno scheletro di parete S-Space (secondo Peponis et al 1997) partizionando l'area con linee originate perpendicolarmente dai punti medi tra coppie vicine di elementi di pareti esterne (finestre o porte).
    • Infine, le pareti vengono selezionate dallo scheletro S-space che "corrisponde il più possibile alle pareti cellulari Voronoi".

3
Puoi includere foto? Sarebbe grandioso. Ho sfogliato la carta e le stanze che hanno generato sembravano buone da un POV architettonico.
congusbongus,

Metodo molto interessante, dovrò esaminarlo più da vicino per eventuali idee che potrei essere in grado di togliermi.
Draco18s

Sono venuto qui per rilassarmi dal lavoro ... Sorprende il mio argomento di ricerca. Sono troppo pigro per scrivere una risposta basata sulla mia ricerca (ho ancora progettato solo le ossa nude dell'algoirthm, quindi non ne vale la pena comunque) o descrivendo gli approcci di Danil Nagy al problema, quindi lascerò questo qui autodeskresearch.com/publications/…
Felipe Gutierrez
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.