Maze Generation [chiuso]


41

So che esiste un (vecchio) thread simile a questo ( qui ), ma vorrei riavviarlo con alcune modifiche.

L'obiettivo: generare un labirinto dall'aspetto casuale usando un algoritmo di propria scelta, quindi produrre graficamente il labirinto (stampa conteggi).

  • La larghezza e l'altezza sono determinate da te.
  • Dovrebbe esserci almeno un percorso da almeno un'entrata ad almeno un'uscita.
  • Il formato del labirinto (come lo visualizzi, segna l'ingresso / i o le uscite) dipende anche da te.
  • Più è bello, meglio è.
  • I labirinti triviali (ad es. Labirinti vuoti, labirinti reticolari, labirinti di dimensioni 1x1) sono scoraggiati.
  • Sono ammessi cicli nel labirinto e, se incoraggiati, sono incoraggiati, se il risultato è ragionevole.
  • Abuso di lingua incoraggiato.
  • Il labirinto dovrebbe apparire ragionevolmente casuale (ma va bene anche un algoritmo completamente deterministico (ad esempio caotico) che genera questo).

Modifica: l'obiettivo principale qui è quello di realizzare l'implementazione più piccola possibile. Tuttavia, voglio consentire un margine di manovra all'interno di tale vincolo per incoraggiare la lucentezza. Ho deliberatamente lasciato esattamente quali sono le "caratteristiche" del labirinto senza limiti, ma come linea guida approssimativa dovresti provare a mettere la maggior quantità di botto nel minimo lessico lessicale.


4
Anche "Il più bello, il migliore" sembra difficilmente tangibile (o semplicemente irrilevante) per una sfida di code-golf. Forse un concorso di popolarità sarebbe la scelta migliore se sei interessato a risultati piuttosto carini.
Martin Ender,

5
Quindi è davvero un golf da codice o è piuttosto un concorso di popolarità?
l0b0,

2
Come altro suggerimento, se vuoi incentivare sia i codici brevi sia i labirinti, potresti renderlo una sfida al codice e dichiarare che il vincitore sarà selezionato da un punteggio che è una miscela di lunghezza del codice e voti positivi, anche se lo farà dipende da te per determinare il punteggio totale di ogni risposta, perché includere il numero attuale di voti nel post è un po 'inutile.
Martin Ender,

3
Penso che ogni risposta dovrebbe spiegare ciò che costituisce gli ingressi e le uscite in ogni labirinto (così come, che cos'è un muro e che cos'è un passaggio), in modo che possiamo valutare il secondo proiettile.
LarsH,

2
@Geobits Non mi dispiacerebbe troppo, ma quindi il mio suggerimento di renderlo effettivamente una sfida del codice con punteggio combinato per lunghezza e voti del codice. Ciò incoraggerebbe esattamente ciò che l'OP vuole: codice breve per labirinti interessanti.
Martin Ender,

Risposte:


10

C: 265 253 byte

#define f(v)for(v=0;v<k;++v)
#define d(q,n)case q:r(c+n,c+2*n);
z[4225],i,j,k=65;r(p,c){if(!z[c]){z[p]=z[c]=1;f(p)switch(rand()%4){d(0,-k)d(1,k)d(2,-1)d(3,1)}}}main(){f(i)z[i]=z[i+4160]=z[i*k]=z[i*k+64]=z[4157]=1;r(67,132);f(i)f(j)putchar(33-z[i*k+j]);}

(Richiede un terminale di 65 caratteri) Genera un labirinto 31x31 relativamente casuale con un percorso garantito dall'ingresso all'uscita.

Esempio di output (con terminale simulato a 65 caratteri):

 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
 !     !       !   !       !     !           !             !   ! 
 !!!!! !!! !!! ! !!! ! !!! ! !!! !!!!!!! !!! !!!!!!!!! !!! ! ! ! 
 !   !   !   ! !     ! ! ! ! ! ! !       !   !         !   ! ! ! 
 ! !!!!! !!! ! !!!!!!! ! ! ! ! ! ! !!!!!!! !!! ! !!!!!!! !!! ! ! 
 !     !     !         ! !   !   !     !   !   ! !     !   ! ! ! 
 ! !!! !!!!!!!!!!!!!!!!! !!!!! !!! !!! !!! ! ! !!! !!! !!! !!! ! 
 !   !         !     !   !     !     !   ! ! ! !     !   !   ! ! 
 !!!!!!!!!!! ! ! !!! !!! ! !!!!!!!!!!!!! ! !!! ! !!!!!!! !!! ! ! 
 !           !   !       ! !             !   !     !     !     ! 
 ! !!!!!!! !!!!!!! !!!!!!! ! !!!!!!!!!!!!!!! !!!!!!! !!!!!!!!!!! 
 ! !     ! !   !     !   ! !           !   !       ! !         ! 
 ! !!! ! ! ! ! !!!!!!! ! ! ! !!!!!!!!! ! ! !!!!!!! ! ! !!!!!!! ! 
 !   ! !   ! !       ! !   ! !         ! !       ! ! !   !   ! ! 
 !!! ! !!!!! !!!!!!! ! !!!!!!! !!!!!!!!! !!! !!!!! ! !!! ! !!! ! 
 !   !   ! ! !       !   !     !   !     ! !           ! !   ! ! 
 ! !!!!! ! ! ! !!!!!!!!! ! !!!!! !!! !!!!! !!!!!!!!!!! ! ! ! ! ! 
 ! !       ! !   !   !   ! !       ! !       !   !     ! ! ! ! ! 
 ! !!!!!!!!! !!! ! ! ! !!! !!!!!!! ! !!!!!!! ! ! !!!!!!! !!! ! ! 
 !             !   ! !   !       ! !     !   ! !             ! ! 
 !!!!!!!!!!!!!!!!!!! !!! !!!!!!! ! !!!!! ! !!! !!!!!!!!!!!!!!! ! 
 !               !   !   !       !         !   !     !   !     ! 
 ! !!!!!!!!!!!!! ! ! ! !!! !!!!!!! !!!!!!!!! !!! !!! !!! ! !!! ! 
 ! !   !       !   ! ! ! !     ! ! ! !     !     !   !   !   ! ! 
 ! ! ! !!!!! !!!!!!! ! ! ! !!! ! ! ! ! !!! !!!!!!! !!! !!!!! !!! 
 !   ! !   !       ! ! !     ! !     ! ! !     !   !       !   ! 
 !!!!! ! ! !!! !!! ! ! !!!!!!! !!!!!!! ! ! !!! ! !!!!!!!!! !!! ! 
 !     ! !   !   !   !       !       ! ! ! !   !   !         ! ! 
 ! !!!!! !!! !!! !!!!!!!!!!! !!!!!!! ! ! ! !!!!!!! ! !!!!!!! ! ! 
 !         ! !           !   !       ! ! !     !   ! !       ! ! 
 !!!!!!!!!!! !!!!!!!!!!! ! !!! !!!!!!! ! !!!!! ! !!! !!!!!!!!! ! 
 !         !     !     ! ! !       !   !     ! !     !         ! 
 ! !!!!!!! !!!!! ! !!! !!! !!!!!!! ! !!!!! ! ! !!!!! ! !!!!!!!!! 
 ! !     !     !   ! !   !       ! !       ! !       !         ! 
 ! ! !!! !!!!! ! !!! !!! !!!!!!! ! !!!!!!!!! !!!!!!!!!!!!!!!!! ! 
 !     !     ! !   !   ! !     ! !       !   ! !     !         ! 
 !!!!!!!!!!! ! !!! !!! ! ! ! !!! ! ! !!!!! !!! ! !!! ! !!!!!!! ! 
 !           ! !       !   ! !   ! !       !   ! ! ! !     !   ! 
 ! !!!!!!!!!!! !!!!!!!!!!!!! ! !!! !!!!!!!!!!! ! ! ! ! !!! ! !!! 
 !       !   !             ! ! ! !   !         ! !   !   ! ! ! ! 
 !!!!!!! !!! !!!!!!!!!!!!! ! ! ! !!! ! !!!!!!! ! !!! !!!!! ! ! ! 
 !       !         !     ! ! ! !   !   !     ! !   !       !   ! 
 ! !!!!!!! !!!!!!! ! !!!!! ! ! !!! !!!!!!! ! ! !!! !!!!!!!!!!!!! 
 !   !         ! !   !       ! !           ! !   !             ! 
 ! ! ! !!!!!!! ! ! !!! !!!!!!! ! !!!!!!!!!!! ! !!!!!!!!!!!!!!! ! 
 ! ! ! !     ! !   !   ! !     !   !   !     ! !               ! 
 ! ! !!! !!! ! !!!!! !!! ! !!!!! ! ! ! !!!!!!! ! !!!!!!!!!!!!! ! 
 ! !   !   ! !   !       !   !   !   !         ! !         !   ! 
 !!!!! !!! ! !!! ! !!!!!!!!! !!!!!!! !!!!!!!!!!! !!!!! !!!!! !!! 
 !     !   !   !   !       !       !       !   !     !       ! ! 
 ! !!!!! !!!!! !!!!! !!!!! !!!!!!! !!!!!!!!! ! !!!!! !!!!!!! ! ! 
 !           !     ! !   !   !   !           !   !   !     !   ! 
 ! !!!!!!!!! !!!!! ! !!! ! !!! ! !!!!!!!!!!!!!!! ! !!! !!! !!! ! 
 ! !     !       ! !     !     !     !         ! !       !   ! ! 
 !!! !!! !!!!!!!!! !!!!! !!!!!!!!! ! !!!!!!! !!! ! !!!!!!!!! ! ! 
 !   !     !   !   !   ! !       ! !         !   ! !         ! ! 
 ! !!!!!!! ! ! ! ! !!! ! !!!!!!! ! !!!!!!!!! ! !!!!! !!!!!!!!! ! 
 !       !   !   ! !   !         !   ! !   ! ! !     !       ! ! 
 ! !!!!! !!!!!!!!! ! !!!!!!!!!!! !!! ! ! ! ! ! ! !!!!! !!!!! ! ! 
 ! !     !           !         ! ! ! !   !   ! !   !   !     ! ! 
 ! ! !!!!!!!!!!!!!!!!! !!! !!!!! ! ! !!!!!!!!! !!! ! !!!!!!!!! ! 
 ! !                     !         !               !           ! 
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! 

2
Non hai nemmeno bisogno int p,int c. p,cè abbastanza ...
Chubakueno,

Ah, grazie per averlo sottolineato
Dendrobium

34

Mathematica, 144 132 byte

Dall'inizio, conosciamo tutti il modo più efficiente di disegnare un labirinto .

c=0;Graphics@Most[Join@@{Circle[{0,0},i,{a=c-(r=Random[](d=2Pi-1/i)&)[],a+d}],Line[{{i},{i+1}}.{{Cos[c=a+r[]],Sin@c}}]}~Table~{i,9}]

Ungolfed ed esempio di output:

enter image description here

Certo, le linee sono le pareti. Sei il minotauro che parte dal centro e deve uscire.


4
Questo è carino, e il codice è breve, ma direi che è verso la fine "banale labirinto" dello spettro.
LarsH,

2
Hai ragione sul fatto che ingrandirlo non cambierebbe la banalità. Il punto è che risolvere questo labirinto è un processo lineare: ad ogni giuntura puoi scoprire rapidamente se hai preso la svolta sbagliata, senza dover "ricorrere" in rami più profondi. Le risposte di Ian e di aleph, d'altra parte, sono labirinti "reali": non possono essere risolti in questo modo lineare. Poiché i labirinti banali sono scoraggiati, sarei tentato di sottovalutare questo, ma non ho abbastanza rappresentante.
LarsH,

1
@LarsH sì, siamo d'accordo su questo. Ecco perché ho detto che è il modo più "efficiente" per disegnare un labirinto, non il più "efficace". ;) Tuttavia, può essere semplice, ma non penso che rientri in una categoria con quelli esclusi come "vuoto" o "1x1". Ovviamente, è a discrezione del PO squalificare questa richiesta per la sua semplicità, ma finché non lo fa o cambia il tipo di sfida, non vedo un incentivo a renderlo più complicato / interessante.
Martin Ender,

1
@LarsH detto questo, non sono sicuro che sia dovuto ai loro algoritmi o solo a una caratteristica degli esempi particolari che hanno pubblicato, ma nessuna delle loro risposte ha richiesto di tornare indietro oltre la profondità "1" più di una volta. Quindi, sebbene contengano molta complessità, è comunque tutto in percorsi irrilevanti.
Martin Ender,

1
Questo labirinto non è banale, secondo me, anche se è facile (e il mio labirinto circolare sotto è ancora più banale). Volevo davvero solo impedire blank-canvas / size-1 / etc. "labirinto" s.
imallett,

33

C: 364 byte

#define I int
m[1600],i=0,r;f(I x,I y,I l){m[80*y+x]|=l;I d[]={x-1,y,2,1,x+1,y,1,2,x,y-1,8,4,x,y+1,4,8},
s[]={5,5,5,5},j=0;for(;j<4;){L:r=rand()%4;for(I k=0;k<4;)if(s[k++]==r)goto L;s[j]=r;I*p=d+
4*s[j++],X=p[0],Y=p[1];if(!(X<0|X>79|Y<0|Y>19|m[80*Y+X])){f(X,Y,p[2]);m[80*y+x]|=p[3];}}}
main(){f(0,0,4);m[9]|=4;for(;i<1600;)putchar("#5FMP<HJR;IK:9LN"[m[i++]]+128);}

Nota: in precedenza, ho aggiunto nuove righe per adattarlo alla pagina. Uscita prevista (sul terminale di 80 caratteri) (inizio e fine della nota in alto a sinistra): enter image description here


8
@bwoebi MSPaint in soccorso! IMMAGINE
Geco a soffitto

6
Nota che la mia intenzione era quella di avere il percorso all'interno dei tubi (come qui) .
imallett,

1
@IanMallett Penso che Ceiling Gecko ne fosse consapevole, ma riempire di inondazioni la parete sinistra con un colore ti dà un percorso (non ottimale) che segue lungo la parete sinistra fino a trovare l'uscita. ;)
Martin Ender,

1
Sarei interessato a vedere la versione non giocata di questo codice, se hai tempo.
LarsH

4
Mentre scrivevi questo, eri un programmatore sbalorditivo.
totymedli,

24

Mathematica, 134 130 caratteri

Graph[Range@273,Reap[Do[c@n/._c:>#0[Sow[#<->n];n],{n,RandomSample@AdjacencyList[g=GridGraph@{13,21},c@#=#]}]&@1][[2,1]],Options@g]

maze


In effetti, possiamo usare questo algoritmo per generare un labirinto da qualsiasi grafico (non indirizzato).

Ad esempio, genera un labirinto dal grafico del tour del cavaliere 8 * 8 ( KnightTourGraph[8,8]):

knight's tour graph

Graph[Range@64,Reap[Do[c@n/._c:>#0[Sow[#<->n];n],{n,RandomSample@AdjacencyList[g=KnightTourGraph[8,8],c@#=#]}]&@1][[2,1]],Options@g]

maze2


7
Bel labirinto ... ma non vedo alcun ingresso collegato a un'uscita ...?
bwoebi,

9
Credo che l'idea sia quella di scegliere un nodo casuale (diciamo, in alto a sinistra) come entrata e un altro (in basso a destra) come uscita. Mathematica si assicura che tutti i nodi siano connessi con tutti gli altri nodi, ma - specialmente nel secondo labirinto - scoprire come sono collegati è la parte più difficile.
EagleV_Attnam,

Le linee (bordi del grafico) dovrebbero essere pareti di labirinto o passaggi? Pensavo di saperlo, ma ora non ne sono sicuro.
LarsH,

@LarsH Sono passaggi.
alephalpha,

1
@LarsH Il grafico è collegato, quindi puoi semplicemente prendere due nodi arbitrari, uno come entrata, l'altro come uscita.
alephalpha,

13

Bash, 53 byte

w=(╱ ╲);while true;do echo -n ${w[RANDOM%2]};done

Idea simile al codice C64. Utilizza i caratteri Unicode come barre perché sembrano molto più belli in un terminale che supporta Unicode. Esempio di output su Terminale OS X (font Menlo):

Sample maze output


2
Una volta ho capito questo: yes 'c=(╱ ╲);printf ${c[RANDOM%2]}'|bash. Vedi questo messaggio
gniourf_gniourf

5
Questo si basa su un algoritmo che non può garantirsi risolvibile, che ha molti anni.
Isiah Meadows,

9

JavaScript (ES6), 174

Questo è il labirinto che ho usato in questa altra sfida , appena giocato a golf. È una funzione con 2 parametri: righe e colonne. Il labirinto è totalmente collegato senza loop, quindi qualsiasi posizione può essere il punto iniziale o finale.

(r,c,o=2*c+2,i=2*r*o+o,z=[],F=(p,i=Math.random()*4)=>[o,1,-o,-1].map((s,j,d)=>z[s=p+2*d[j+i&3]]>0&&(z[s]=z[(p+s)/2]=' ',F(s))))=>{for(;i--;)z[i]=i%o?8:`\n`;F(o+2);return''+z}

Esempio

f(7,10)

Produzione

,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
,8, , , ,8, , , , , ,8, , , , , , , , , ,8,
,8, ,8, ,8,8,8, ,8, ,8,8,8,8,8,8,8, ,8, ,8,
,8, , , ,8, , , ,8, , , ,8, , , , , ,8, ,8,
,8, ,8,8,8, ,8,8,8,8,8, ,8, ,8,8,8,8,8, ,8,
,8, ,8, , , , , ,8, ,8, ,8, ,8, , , , , ,8,
,8, ,8, ,8,8,8, ,8, ,8, ,8, ,8, ,8,8,8,8,8,
,8, ,8, ,8, , , ,8, , , , , ,8, ,8, , , ,8,
,8, ,8, ,8, ,8,8,8,8,8,8,8,8,8, ,8, ,8,8,8,
,8, ,8, ,8, , , , , , , ,8, , , ,8, , , ,8,
,8, ,8, ,8,8,8,8,8,8,8, ,8,8,8, ,8,8,8, ,8,
,8, ,8, , , , , , , ,8, , , ,8, , , , , ,8,
,8, ,8,8,8,8,8,8,8,8,8,8,8, ,8,8,8,8,8, ,8,
,8, , , , , , , , , , , , , ,8, , , , , ,8,
,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8

Test

f=
(r,c,o=2*c+2,i=2*r*o+o,z=[],F=(p,i=Math.random()*4)=>[o,1,-o,-1].map((s,j,d)=>z[s=p+2*d[j+i&3]]>0&&(z[s]=z[(p+s)/2]=' ',F(s))))=>{for(;i--;)z[i]=i%o?8:`\n`;F(o+2);return''+z}
    
function update() {    
  O.textContent='';
  [r,c]=I.value.match(/\d+/g)
  O.textContent=f(r,c)
}  

update()
pre { line-height: 0.8em }
Rows,Columns <input id=I oninput='update()' value='8,12'>
<pre id=O></pre>


Non sono sicuro ... la luce o l'area scura è il labirinto? Se è buio, allora ha un grande anello e si può semplicemente rimanere all'esterno quando si sceglie qualsiasi punto come punto di entrata / uscita. Se la luce, allora dovresti aggiungere l'uscita / entrata.
Paŭlo Ebermann,

1
@ PaŭloEbermann è la luce ovviamente, l'area scura è le pareti. Ripetendomi: il labirinto è totalmente collegato senza loop, quindi qualsiasi posizione può essere il punto di partenza o di fine
edc65,

Wow, questo è un labirinto! Rasato alcuni byte e ridotto a 133 byte: twitter.com/aemkei/status/889587308894326785 Ma tutti i crediti dovrebbero andare a te!
aemkei,

@aemkei 8 invece di '#', non riesco a credere di averlo perso in quel momento
edc65,

8

ZX Basic - 54 caratteri

a$="/\":for i=1 to 24*32:print a$(1+int(rnd*2));:next

Produzione

Ecco il labirinto che mostra un percorso attraverso di esso (spazi tra le linee)

sentiero

e un piccolo frammento di quando l'ho fatto per la prima volta (diversi anni fa) e ho trascorso un po 'di tempo a realizzare una grafica migliore.

grafica migliore


2
Hm, sfacciato. ^^ Qual è l'inizio e qual è la fine lì? E i tagli sono i sentieri o le pareti? E qual è la dimensione minima del gap che posso attraversare?
Martin Ender,

2
"Dovrebbe esserci almeno un percorso da almeno un'entrata ad almeno un'uscita." Non vedo alcuna indicazione che questo criterio sia soddisfatto. I muri casuali non creano necessariamente un labirinto.
LarsH,

1
@ m.buettner: sto immaginando che le barre siano muri e che dovremmo visualizzarlo come se ci fosse spazio zero tra le file e tra le colonne. Quindi i caratteri 2x2 in basso a sinistra formano una forma di diamante (quadrata) totalmente chiusa.
LarsH,

@LarsH sì, l'ho pensato. Questo è solo un altro punto del tuo caso sulla domanda del PO che le persone dovrebbero indicare quali sono l'inizio e la fine. Inoltre, questo schema non consente nemmeno giunzioni. Puoi avere solo quei quadrati chiusi o percorsi tortuosi (che potrebbero anche essere anelli chiusi).
Martin Ender,

+1 per la grafica migliorata e la visualizzazione del percorso. Immagino che dati così tanti potenziali ingressi ed uscite, la probabilità di avere "almeno un percorso da almeno un ingresso ad almeno un'uscita" è piuttosto alta!
LarsH,

8

BBC BASIC, 18 byte

Un miglioramento della lunghezza nella versione a ciclo infinito C64 a 23 byte di @nneonneo. VDU invia un singolo carattere al controller VDU: 2 + 1 * 45 = ASCII 47 /o 2 + 2 * 45 = ASCII 92\

  VDU2+RND(2)*45:RUN

BBC BASIC, 35 byte / 107 95 byte

35 byte è solo per l'ultima riga, che fornisce un labirinto di 25 righe con layout a 40 colonne. MODE1 assicura che non rimanga spazio aggiuntivo tra le linee. Il resto del programma è facoltativo e migliora la formattazione. Le istruzioni VDU23 ridefiniscono il carattere per i caratteri 47 e 92 (8 byte che formano una bitmap 8x8). Includo un pixel leggero in tutti e quattro gli angoli per impedire che le linee diritte vengano pizzicate. L'effetto collaterale di questo è che un punto appare nei diamanti vuoti. 107 byte totali di cui 2 newline.

  VDU23,47,131,7,14,28,56,112,224,193
  VDU23,92,193,224,112,56,28,14,7,131
  MODE9FORa=0TO999VDU2+RND(2)*45:NEXT

modificare questo programma può essere abbreviato a 95 byte codificando alcuni dei codici VDU a 8 bit in piccoli valori endian a 16 bit (indicati da un punto e virgola dopo di essi anziché una virgola) e rappresentando l'istruzione MODE come una coppia di codici VDU, come segue .

VDU23,47,1923;7182;28728;49632;23,92,57537;14448;3612;33543;22,9:FORa=0TO999VDU2+RND(2)*45:NEXT

Produzione

Utilizzo di BBC Basic per Windows da bbcbasic.co.uk

Solo ultima riga, 35 byte

inserisci qui la descrizione dell'immagine

Intero programma, 107 95 byte

Come ho commentato la risposta di @ Brian, la barra divide il quadrato in 2 triangoli scuri, ognuno dei quali ha esattamente 2 entrate / uscite. Ciò garantisce un percorso (banale, non ramificato) da qualsiasi punto sul bordo del labirinto a qualche altro punto sul bordo del labirinto. Molti di questi sono molto brevi, ma sembrano essercene sempre alcuni lunghi. Naturalmente, nel mezzo del labirinto ci sono anche alcuni anelli.

Poiché altre risposte non l'hanno menzionato, vorrei dare una buona occhiata alle aree chiare. Questi sono delimitati da aree scure, quindi come corollario dell'affermazione fatta sopra, un'area chiara delimitata esternamente da N aree scure tocca il bordo del campo in corrispondenza di N (esattamente altrettanti) punti. Pertanto si verificano alcune aree di luce abbastanza grandi, che formano labirinti ramificati interessanti.

Nell'esempio seguente, puoi vedere l'output non elaborato (monocromatico) dal mio programma. Sotto quello (usando Windows Paint) ho colorato le due aree scure più lunghe in blu. Quindi ho colorato l'area luminosa più grande in giallo e le due aree delimitate dal blu in rosso e verde. I labirinti gialli, verdi (e persino rossi) sono piuttosto interessanti e non banali.

inserisci qui la descrizione dell'immagine

EDIT - Picking automatico di labirinti e selezione di inizio / fine

Per un'altra riga (59 caratteri), il programma può scegliere automaticamente fino a 6 labirinti scegliendo casualmente i quadrati e riempiendo i colori rosso, verde, giallo, blu, magenta e ciano. Non trova sempre 6 interi, perché se sceglie un quadrato casuale che è già stato colorato non fa nulla.

Il resto del codice seguente seleziona un inizio per ciascun colore scansionando ciascuna colonna dall'alto verso il basso e da sinistra a destra e selezionando il primo quadrato che incontra. Prende fine scansionando nella direzione opposta.

Questo produce una serie di labirinti colorati e intrecciati. A volte sono così intrecciati che sembra che i labirinti debbano attraversare da qualche parte. Ma ovviamente no!

Codice aggiuntivo e output 59 + 187 = 246 caratteri aggiuntivi da aggiungere alla fine del programma originale (per il miglioramento oltre la specifica della domanda)

  GCOL135FORa=1TO6GCOLa FILLRND(40)*32-16,RND(25)*32+208:NEXT   :REM set background to grey so fill can identify. For each colour 1 to 6, pick a point in the centre of a character and flood fill (characters are logically 32x32 although they are physically only 8x8 pixels.)
  f=126:g=126                                                   :REM flags 1111110 to indicate which starts and ends have not been allocated yet
  FORx=0TO39FORy=0TO24                                          :REM maze is 40x25. There is some blank space at the bottom of the screen (32 rows total)
  p=POINT(x*32+16,1008-y*32)                                    :REM check start point. Text origin is at top of screen, Graphics origin is at bottom, 1280x1024 logical. therefore y offset is 1024-32/2=1008.
  IFf AND2^p f=f-2^p:VDU31,x,y,17,p,79                          :REM if start for colour P has not been allocated yet, allocate it now. VDU31,X,Y go to that square. VDU 17,p select text colour. VDU 79 print an "O"                 
  p=POINT(1264-x*32,240+y*32)                                   :REM check end point
  IFg AND2^p g=g-2^p:VDU31,39-x,24-y,17,p,79                    :REM if end for colour P has not been allocated yet, allocate it now.
  NEXT:NEXT
  VDU31;26                                                      :REM get the cursor off the board. Move to (0,26). Semicolon used instead of comma here indicating that 31 is a 16 bit small endian value, equivalent to VDU31,0,26 or PRINTTAB(0,26)

inserisci qui la descrizione dell'immagine


7

C: 235 byte

#define P(X,Y)M[(Y+40)*80+X+40]=rand()%49/6;
#define B(X,Y)P(X,Y)P(Y,X)
M[6400],r,i;main(){for(i=0;i<40;i+=2){int x=i,y=0,e=1-x;while(x>=y)
{B(x,y)B(-x,y)B(-x,-y)B(x,-y)++y;e+=e<0?2*y+1:2*(y-x--);}}for(i=0;
i<6400;)putchar(64>>!M[i++]);}

Nota: in precedenza, ho aggiunto nuove righe per adattarlo alla pagina. Uscita prevista (su terminale a 80 caratteri):inserisci qui la descrizione dell'immagine

Mi dispiace che questo non sia un labirinto molto difficile (in realtà, non è richiesto alcun backtracking agli anelli interni (e dovresti essere in grado di trovare banalmente un percorso dal perimetro al centro). Tuttavia, ha una bella implementazione del cerchio di Bresenham algoritmo di disegno alla base.


È un po 'difficile vedere dove puoi passare e dove non puoi. Devo dire che ho preferito le pipe;) (sia a questa che alla mia presentazione circolare).
Martin Ender,

@ m.buettner: sono davvero d'accordo. Se si modifica il i+=2in i+=3, potrebbe essere più chiaro cosa sta succedendo.
imallett,

6

Ho aiutato mio figlio a fare questo, per imparare un po 'di programmazione: http://jsfiddle.net/fs2000/4KLUC/34/ come ti piace?


17
Se riesci a inserire il tuo codice nel post, fallo. Inoltre, includi un'intestazione come #Language (s) - Bytecount. Se hai usato solo caratteri ASCII nel tuo codice, puoi ottenere un buon conteggio qui . Un riepilogo di ciò che fa il tuo codice, eventuali approfondimenti che potresti aver avuto o qualsiasi cosa intelligente che hai fatto potrebbe essere una bella aggiunta al tuo post. A proposito, Darth Vader rende molto difficile vedere alcune delle linee. Infine, benvenuti a Code Golf!
Rainbolt,

Hai imparato un po 'di programmazione con i tuoi figli e ho imparato un po' di golf. Questo è il mio primo golf e il risultato è ancora piuttosto lungo. Conteggio byte: Originale: 55 + 6822 = 6877. Un po 'riorganizzato : 39 + 3131 = 3170 Golf : 39 + 1593 = 1632
BartekChom

6

Commodore 64 BASIC - 38 byte

10 PRINT CHR$(205.5+RND(1)); : GOTO 10

Questa non è una mia invenzione, sto semplicemente ripetendo un programma molto bello e breve da giorni passati. In effetti, c'è un intero libro chiamato che 10 PRINT CHR$(205.5+RND(1)); : GOTO 10celebra questo pezzo di codice!

Puoi vedere l'output su questo video di YouTube ; ecco una screencap:

YouTube screencap

Qui a questa domanda StackOverflow ci sono più implementazioni di questo programma generatore di labirinto. L'implementazione più breve del programma è il seguente programma BASIC C64 a 23 byte pubblicato dall'autore della domanda:

1?cH(109.5+rN(1));:gO1

dove le lettere minuscole vengono immesse così come sono e le lettere maiuscole vengono immesse utilizzando il tasto Maiusc (questi hanno aspetti diversi su una schermata C64 effettiva).


Non è esattamente la stessa presentazione di Brian? (solo un po 'più corto) E anche la tua risposta di Bash? Quindi anche la domanda qui è: un labirinto senza incroci è ancora un labirinto?
Martin Ender,

nneonneo, +1 per l'attribuzione corretta e onesta di questa grande idea. @ m.buettner L'area non stampata produce labirinti non ramificati come fai notare. Tuttavia (e sono sorpreso che nessun altro lo abbia ancora dimostrato) l'area stampata forma alcuni labirinti ramificati interessanti, non banali (vedi la mia risposta). Sto anche valorizzando il tuo labirinto in quanto ha l'inizio e la fine meglio definiti . Definire l'inizio e la fine di questi labirinti diagonali non è facile.
Level River St,

@ m.buettner 1. Il binario x86 ha solo 10 byte al minimo. 2. Questo è un algoritmo ben rifinito e non è affatto originale, né era destinato a creare un labirinto risolvibile.
Isiah Meadows,

5

Java: 700

Ecco un sommatore a muro ricorsivo. L'algoritmo è delineato su questo sito :

public class Z{int i,j,u=20,v=u,g[][]=new int[v][u];public static void main(String[]a){new Z().d(0,0,20,20,0).p();}int q(int m){return(int)(Math.random()*m);}<T>void z(T m){System.out.print(m);}void p(){for(i=0;i++<u*2;z("_"));for(i=0;i<v;i++){z("\n|");for(j=0;j<u;j++){boolean b=i+2>v,s=g[i][j]%2>0||b;z(s?"_":" ");z(g[i][j]>1||j+2>u?"|":s&(j+1<u&&g[i][j+1]%2>0||b)?"_":" ");}}}Z d(int x,int y,int w,int h,int o){int a=x,b=y,c=a,d=b,e,f;boolean t=o<1;if(t){b+=q(h-2);c+=q(w);}else{a+=q(w-2);d+=q(h);}for(i=t?w:h;i-->0;j=t?a++:b++)if(a!=c&&b!=d)g[b][a]|=t?1:2;e=t?w:a-x+1;f=t?b-y+1:h;if(e>2&&f>2)d(x,y,e,f,e<f?0:1);e=t?w:x+w-a-1;f=t?y+h-b-1:h;if(e>2&&f>2)d(t?x:a+1,t?b+1:y,e,f,e<f?0:1);return this;}}

Fondamentalmente, divide ogni rettangolo in due con un muro (e passaggio), quindi divide quelli in due, ecc. Genera un labirinto "perfetto" - uno senza cicli - che ha un percorso da ogni punto a ogni altro punto. Un sacco di vicoli ciechi, quindi non è "banale" in alcun senso per i labirinti più grandi.

Quindi, l'ingresso e l'uscita possono essere decisi arbitrariamente. Se devo sceglierne uno, dirà solo in alto / a sinistra e in basso / a destra.

È disegnato in ASCII a doppia larghezza, quindi è una buona idea reindirizzare l'output in un file se ne stai eseguendo uno di qualsiasi dimensione. Ecco un 20x20 in console:

20x20

E un 100x100 in notepad ++ (ho dovuto ridurre lo zoom per ottenere tutto, quindi è un po '... piccolo ):

100x100

Codice con interruzioni di riga:

public class Z{
    int i,j,u=20,v=u,g[][]=new int[v][u];
    public static void main(String[]a){
        new Z().d(0,0,20,20,0).p();
    }

    int q(int m){return(int)(Math.random()*m);}
    <T>void z(T m){System.out.print(m);}

    void p(){
        for(i=0;i++<u*2;z("_"));
        for(i=0;i<v;i++){
            z("\n|");
            for(j=0;j<u;j++){
                boolean b=i+2>v,s=g[i][j]%2>0||b;
                z(s?"_":" ");
                z(g[i][j]>1||j+2>u?"|":s&(j+1<u&&g[i][j+1]%2>0||b)?"_":" ");
            }
        }
    }

    Z d(int x,int y,int w,int h,int o){
        int a=x,b=y,c=a,d=b,e,f;
        boolean t=o<1;
        if(t){
            b+=q(h-2);
            c+=q(w);
            }
        else{
            a+=q(w-2);
            d+=q(h);
        }

        for(i=t?w:h;i-->0;j=t?a++:b++)
            if(a!=c&&b!=d)
                g[b][a]|=t?1:2;

        e=t?w:a-x+1;f=t?b-y+1:h;
        if(e>2&&f>2)d(x,y,e,f,e<f?0:1);
        e=t?w:x+w-a-1;f=t?y+h-b-1:h;
        if(e>2&&f>2)d(t?x:a+1,t?b+1:y,e,f,e<f?0:1);
        return this;
    }
}

2

ZX Basic: 281 caratteri

Questo è più un labirinto "corretto", meno golfista, ma più pazzo. Il cosiddetto algoritmo del labirinto binario, ogni cella può avere un'uscita che scende o scende, ma non entrambe. (Ora include Start contrassegnato "S" e End "E", per evitare di andare dritto lungo un lato).

Il "::" è il modo di ZXB di inserire caratteri grafici Spectrum in un file di testo, equivale a un carattere di blocco venduto.

randomize:border 1:paper 1:ink 6:cls
for x=0 to 30 step 2
 for y=0 to 20 step 2
  r=1+int(rnd*2)
  if x=30 and r=1 then 
   r=2
  end if
  if y=20 and r=2 then
   r=1
  end if
  print at y,x;"\::"
  print at y+(r=2),x+(r=1);"\::"
 next
next
print inverse 1;at 0,0;"S";at 20,31;"E"

Labirinto


2
No, in realtà intendevo scambiare l'inizio e la fine (inizio in basso a destra, fine in alto a sinistra). Come è banale, perché a causa delle regole devi solo andare giù e giusto tutto il tempo per raggiungere la fine.
Martin Ender,

1
Anche se l'inizio e la fine sono invertiti, il labirinto ha la proprietà (forse interessante) che il percorso corretto si sposterà solo verso l'alto e a sinistra. Il labirinto non è più banale, però, perché ci sono molti punti in cui puoi andare in due modi.
Kevin - Ripristina Monica il

1

C- 244

#include <unistd.h>
#include <windows.h>
int main(i,j,rv,rs){srand( time(0));for (i = 0; i < 80; i++)for (j = 0; j <50 ; j++){rv = rand() %10;rs = rand() %100;if(rs < 10 || rs  > 90)continue;if(rv<4){gotoxy(i,j);printf("%c", '#');}}return 0;}

Ecco come appare:

Labirinto

Nota: questa soluzione è ispirata al livello di gioco 8 non attendibile : nel bosco.

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.