Maze Generation [fermé]

41

Je sais qu'il existe un (vieux) thread similaire à celui-ci ( ici ), mais j'aimerais le redémarrer avec quelques modifications.

L'objectif: générer un labyrinthe d' apparence aléatoire à l' aide d'un algorithme de votre choix, puis générer le labyrinthe sous forme graphique (le nombre d'impressions).

  • La largeur et la hauteur sont déterminées par vous.
  • Il devrait y avoir au moins un chemin d’au moins une entrée à au moins une sortie.
  • Le format du labyrinthe (comment vous l'affichez, marquez les entrées ou les sorties) dépend également de vous.
  • Le plus joli, mieux c'est.
  • Les labyrinthes triviaux (par exemple, les labyrinthes vierges, les labyrinthes en treillis, les labyrinthes de taille 1x1) sont déconseillés.
  • Les cycles dans le labyrinthe sont autorisés et sont encouragés si le résultat est raisonnable.
  • Abus de langage encouragé.
  • Le labyrinthe doit avoir une apparence raisonnablement aléatoire (mais un algorithme complètement déterministe (par exemple chaotique) générant ceci est également utile).

Edit: l'objectif principal est de réaliser la plus petite implémentation possible. Cependant, je souhaite laisser une marge de manœuvre dans le cadre de cette contrainte pour encourager la brillance. J'ai délibérément laissé exactement quelles «fonctionnalités» le labyrinthe est ouvert, mais comme ligne de conduite approximative, vous devriez essayer de placer le maximum de coup dans le dollar lexical.

imallett
la source
4
Aussi, "Le plus beau, le meilleur" semble difficilement tangible (ou simplement hors de propos) à un défi de code-golf. Peut-être qu'un concours de popularité serait le meilleur choix si vous êtes intéressé par de jolis résultats.
Martin Ender
5
Alors, est-ce vraiment du code-golf ou est-ce plutôt un concours de popularité?
l0b0
2
Une autre suggestion, si vous voulez encourager à la fois les codes courts et les labyrinthes ordonnés, vous pouvez en faire un défi de code et déclarer que le gagnant sera sélectionné selon un score mêlant longueur du code et upvotes - bien que À vous de déterminer le score total de chaque réponse, car l’inclusion du nombre actuel de votes positifs dans le message est un peu inutile.
Martin Ender
3
Je pense que chaque réponse devrait expliquer ce qui constitue les entrées et les sorties dans chaque labyrinthe (ainsi que ce qui est un mur et ce qui est un passage), afin que nous puissions évaluer la deuxième puce.
LarsH
2
@Geobits Cela ne me dérangerait pas trop, mais c'est pourquoi je suggère d'en faire un défi de code avec une notation combinée de la longueur du code et des votes. Cela encouragerait exactement ce que le PO veut: un code court pour des labyrinthes intéressants.
Martin Ender

Réponses:

10

C: 265 253 octets

#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]);}

(Nécessite un terminal de 65 caractères) Génère un labyrinthe relativement aléatoire de 31x31 avec un chemin garanti de l’entrée à la sortie.

Exemple de sortie (avec terminal simulé à 65 caractères):

 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
 !     !       !   !       !     !           !             !   ! 
 !!!!! !!! !!! ! !!! ! !!! ! !!! !!!!!!! !!! !!!!!!!!! !!! ! ! ! 
 !   !   !   ! !     ! ! ! ! ! ! !       !   !         !   ! ! ! 
 ! !!!!! !!! ! !!!!!!! ! ! ! ! ! ! !!!!!!! !!! ! !!!!!!! !!! ! ! 
 !     !     !         ! !   !   !     !   !   ! !     !   ! ! ! 
 ! !!! !!!!!!!!!!!!!!!!! !!!!! !!! !!! !!! ! ! !!! !!! !!! !!! ! 
 !   !         !     !   !     !     !   ! ! ! !     !   !   ! ! 
 !!!!!!!!!!! ! ! !!! !!! ! !!!!!!!!!!!!! ! !!! ! !!!!!!! !!! ! ! 
 !           !   !       ! !             !   !     !     !     ! 
 ! !!!!!!! !!!!!!! !!!!!!! ! !!!!!!!!!!!!!!! !!!!!!! !!!!!!!!!!! 
 ! !     ! !   !     !   ! !           !   !       ! !         ! 
 ! !!! ! ! ! ! !!!!!!! ! ! ! !!!!!!!!! ! ! !!!!!!! ! ! !!!!!!! ! 
 !   ! !   ! !       ! !   ! !         ! !       ! ! !   !   ! ! 
 !!! ! !!!!! !!!!!!! ! !!!!!!! !!!!!!!!! !!! !!!!! ! !!! ! !!! ! 
 !   !   ! ! !       !   !     !   !     ! !           ! !   ! ! 
 ! !!!!! ! ! ! !!!!!!!!! ! !!!!! !!! !!!!! !!!!!!!!!!! ! ! ! ! ! 
 ! !       ! !   !   !   ! !       ! !       !   !     ! ! ! ! ! 
 ! !!!!!!!!! !!! ! ! ! !!! !!!!!!! ! !!!!!!! ! ! !!!!!!! !!! ! ! 
 !             !   ! !   !       ! !     !   ! !             ! ! 
 !!!!!!!!!!!!!!!!!!! !!! !!!!!!! ! !!!!! ! !!! !!!!!!!!!!!!!!! ! 
 !               !   !   !       !         !   !     !   !     ! 
 ! !!!!!!!!!!!!! ! ! ! !!! !!!!!!! !!!!!!!!! !!! !!! !!! ! !!! ! 
 ! !   !       !   ! ! ! !     ! ! ! !     !     !   !   !   ! ! 
 ! ! ! !!!!! !!!!!!! ! ! ! !!! ! ! ! ! !!! !!!!!!! !!! !!!!! !!! 
 !   ! !   !       ! ! !     ! !     ! ! !     !   !       !   ! 
 !!!!! ! ! !!! !!! ! ! !!!!!!! !!!!!!! ! ! !!! ! !!!!!!!!! !!! ! 
 !     ! !   !   !   !       !       ! ! ! !   !   !         ! ! 
 ! !!!!! !!! !!! !!!!!!!!!!! !!!!!!! ! ! ! !!!!!!! ! !!!!!!! ! ! 
 !         ! !           !   !       ! ! !     !   ! !       ! ! 
 !!!!!!!!!!! !!!!!!!!!!! ! !!! !!!!!!! ! !!!!! ! !!! !!!!!!!!! ! 
 !         !     !     ! ! !       !   !     ! !     !         ! 
 ! !!!!!!! !!!!! ! !!! !!! !!!!!!! ! !!!!! ! ! !!!!! ! !!!!!!!!! 
 ! !     !     !   ! !   !       ! !       ! !       !         ! 
 ! ! !!! !!!!! ! !!! !!! !!!!!!! ! !!!!!!!!! !!!!!!!!!!!!!!!!! ! 
 !     !     ! !   !   ! !     ! !       !   ! !     !         ! 
 !!!!!!!!!!! ! !!! !!! ! ! ! !!! ! ! !!!!! !!! ! !!! ! !!!!!!! ! 
 !           ! !       !   ! !   ! !       !   ! ! ! !     !   ! 
 ! !!!!!!!!!!! !!!!!!!!!!!!! ! !!! !!!!!!!!!!! ! ! ! ! !!! ! !!! 
 !       !   !             ! ! ! !   !         ! !   !   ! ! ! ! 
 !!!!!!! !!! !!!!!!!!!!!!! ! ! ! !!! ! !!!!!!! ! !!! !!!!! ! ! ! 
 !       !         !     ! ! ! !   !   !     ! !   !       !   ! 
 ! !!!!!!! !!!!!!! ! !!!!! ! ! !!! !!!!!!! ! ! !!! !!!!!!!!!!!!! 
 !   !         ! !   !       ! !           ! !   !             ! 
 ! ! ! !!!!!!! ! ! !!! !!!!!!! ! !!!!!!!!!!! ! !!!!!!!!!!!!!!! ! 
 ! ! ! !     ! !   !   ! !     !   !   !     ! !               ! 
 ! ! !!! !!! ! !!!!! !!! ! !!!!! ! ! ! !!!!!!! ! !!!!!!!!!!!!! ! 
 ! !   !   ! !   !       !   !   !   !         ! !         !   ! 
 !!!!! !!! ! !!! ! !!!!!!!!! !!!!!!! !!!!!!!!!!! !!!!! !!!!! !!! 
 !     !   !   !   !       !       !       !   !     !       ! ! 
 ! !!!!! !!!!! !!!!! !!!!! !!!!!!! !!!!!!!!! ! !!!!! !!!!!!! ! ! 
 !           !     ! !   !   !   !           !   !   !     !   ! 
 ! !!!!!!!!! !!!!! ! !!! ! !!! ! !!!!!!!!!!!!!!! ! !!! !!! !!! ! 
 ! !     !       ! !     !     !     !         ! !       !   ! ! 
 !!! !!! !!!!!!!!! !!!!! !!!!!!!!! ! !!!!!!! !!! ! !!!!!!!!! ! ! 
 !   !     !   !   !   ! !       ! !         !   ! !         ! ! 
 ! !!!!!!! ! ! ! ! !!! ! !!!!!!! ! !!!!!!!!! ! !!!!! !!!!!!!!! ! 
 !       !   !   ! !   !         !   ! !   ! ! !     !       ! ! 
 ! !!!!! !!!!!!!!! ! !!!!!!!!!!! !!! ! ! ! ! ! ! !!!!! !!!!! ! ! 
 ! !     !           !         ! ! ! !   !   ! !   !   !     ! ! 
 ! ! !!!!!!!!!!!!!!!!! !!! !!!!! ! ! !!!!!!!!! !!! ! !!!!!!!!! ! 
 ! !                     !         !               !           ! 
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! 
Dendrobium
la source
2
Tu n'as même pas besoin int p,int c. p,cest suffisant ...
chubakueno
Ah, merci de l'avoir signalé
Dendrobium
34

Mathematica, 144 132 octets

Depuis sa création, nous connaissons tous le moyen le plus efficace de dessiner un labyrinthe .

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 et exemple de sortie:

entrez la description de l'image ici

Bien sûr, les lignes sont les murs. Vous êtes le minotaure qui commence au centre et doit sortir.

Martin Ender
la source
4
C'est joli, et le code est court, mais je dirais que c'est vers le "labyrinthe trivial" du spectre.
LarsH
2
Vous avez raison de dire que le grossir ne changerait rien à la banalité. Le fait est que la résolution de ce labyrinthe est un processus linéaire: à chaque moment, vous pouvez rapidement savoir si vous avez pris le mauvais tournant, sans avoir à "récidiver" dans des branches plus profondes. Les réponses de Ian et d'Aleph, d'un autre côté, sont de "vrais" labyrinthes: elles ne peuvent pas être résolues de cette manière linéaire. Puisque les labyrinthes triviaux sont découragés, je serais tenté de voter contre celui-ci, mais je n'ai pas assez de représentants.
LarsH
1
@LarsH Oui, nous sommes d'accord sur cela. C'est pourquoi j'ai dit que c'était le moyen le plus "efficace" de dessiner un labyrinthe, et non le plus "efficace". ;) Pourtant, cela peut être simple, mais je ne pense pas que cela tombe dans une catégorie avec les exclus, comme "vide" ou "1x1". Bien sûr, c'est la discrétion du PO de disqualifier cette soumission pour sa simplicité, mais tant qu'il ne le fait pas ou ne change pas le type de défi, je ne vois pas d'incitation à la rendre plus compliquée / intéressante.
Martin Ender
1
@LarsH Cela étant dit, je ne suis pas sûr que cela soit dû à leurs algorithmes ou simplement à une caractéristique des exemples particuliers qu'ils ont publiés, mais aucune de leurs réponses n'exigeait de revenir plus d'une fois au-delà de la profondeur "1". Ainsi, même si elles comportent beaucoup de complexité, elles s'inscrivent dans des chemins qui ne sont de toute façon pas pertinents.
Martin Ender
1
Ce labyrinthe n’est pas trivial, à mon avis, même s’il est facile (et mon labyrinthe circulaire ci-dessous est encore plus trivial). Je voulais vraiment juste éviter le blank-canvas / size-1 / etc. "labyrinthe" s.
imallett
33

C: 364 octets

#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);}

Remarque: dans ce qui précède, j'ai ajouté des nouvelles lignes pour l'adapter à la page. Sortie attendue (sur un terminal à 80 caractères) (notez le début et la fin en haut à gauche): entrez la description de l'image ici

imallett
la source
8
@bwoebi MSPaint à la rescousse! IMAGE
Gecko au plafond
6
Notez que mon intention était de placer le chemin dans les tuyaux (comme ici) .
imallett
1
@IanMallett Je pense que Ceiling Gecko était conscient de cela, mais remplir le mur de gauche d'une couleur vous donne un chemin (non optimal) le long du mur de gauche jusqu'à ce que vous trouviez la sortie. ;)
Martin Ender
1
Je serais intéressé de voir la version non jouée de ce code, si vous en avez le temps.
LarsH
4
Pendant que vous écriviez ceci, vous étiez un codeur de labyrinthe.
totymedli
24

Mathematica, 134 130 caractères

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]

Labyrinthe


En fait, nous pouvons utiliser cet algorithme pour générer un labyrinthe à partir de n’importe quel graphe (non dirigé).

Par exemple, générez un labyrinthe à partir du graphe de la tournée du chevalier 8 * 8 ( KnightTourGraph[8,8]):

graphique de la tournée du chevalier

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

Alephalpha
la source
7
Beau labyrinthe… mais je ne vois aucune entrée reliée à une sortie…?
bwoebi
9
Je crois que l’idée est de choisir un nœud aléatoire (par exemple, en haut à gauche) comme entrée et un autre (en bas à droite) comme sortie. Mathematica s'assure que tous les nœuds sont connectés à tous les autres nœuds, mais - surtout dans le deuxième labyrinthe - trouver la manière dont ils sont connectés est la partie la plus difficile.
EagleV_Attnam
Les lignes (bords du graphique) sont-elles supposées être des murs de labyrinthe ou des passages? Je pensais que je savais, mais maintenant je ne suis pas sûr.
LarsH
@LarsH Ce sont des passages.
Alephalpha
1
@LarsH Le graphique est connecté, vous pouvez donc simplement prendre deux nœuds arbitraires, l'un en tant qu'entrée, l'autre en tant que sortie.
Alephalpha
13

Bash, 53 octets

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

Idée similaire au code C64. Utilise des caractères Unicode en tant que barres obliques car ils sont beaucoup plus agréables dans un terminal prenant en charge Unicode. Exemple de sortie sur terminal OS X (police Menlo):

Sample maze output

Nneonneo
la source
2
Une fois , je compris cela: yes 'c=(╱ ╲);printf ${c[RANDOM%2]}'|bash. Voir cet article
gniourf_gniourf
5
Ceci est basé sur un algorithme qui ne peut pas garantir sa résolution, qui a plusieurs années.
Isiah Meadows
9

JavaScript (ES6), 174

C'est le constructeur de labyrinthe que j'ai utilisé dans cet autre défi , juste joué au golf. C'est une fonction avec 2 paramètres: lignes et colonnes. Le labyrinthe est totalement connecté sans boucles, donc n'importe quel emplacement peut être le point de départ ou d'arrivée.

(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}

Exemple

f(7,10)

Sortie

,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

Tester

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>

edc65
la source
Je ne suis pas sûr ... la lumière ou la zone sombre sont-elles le labyrinthe? Si la nuit est sombre, la boucle est grande et il est possible de rester à l’extérieur lorsque vous choisissez un point comme point d’entrée / de sortie. Si la lumière, alors vous devriez ajouter la sortie / entrée.
Paŭlo Ebermann
1
@ PaŭloEbermann c'est la lumière bien sûr, la zone sombre ce sont les murs. Je me répète: le labyrinthe est totalement connecté sans boucles, donc n'importe quel endroit peut être le point de départ ou d'arrivée
edc65
Wow, c'est ahurissant! Coupez quelques octets et réduisez-les à 133: twitter.com/aemkei/status/889587308894326785 Mais tout le crédit devrait aller à vous!
aemkei
@aemkei 8 au lieu de '#', je ne peux pas croire que j'ai loupé ça à l'heure
edc65
8

ZX Basic - 54 caractères

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

Sortie

Voici le labyrinthe montrant une route à travers elle (espaces entre les lignes)

chemin

et un petit extrait de la première fois où je l'ai fait (il y a plusieurs années) et où j'ai passé un peu de temps à faire de meilleurs graphiques.

de meilleurs graphiques

Brian
la source
2
Hm, effronté. ^^ Quel est le début et quelle est la fin là? Et est-ce que les barres obliques sont les chemins ou les murs? Et quelle est la taille minimale de l’intervalle que je peux traverser?
Martin Ender
2
"Il devrait y avoir au moins un chemin d'accès d'au moins une entrée à au moins une sortie." Je ne vois aucune indication que ce critère est rempli. Les murs aléatoires ne créent pas nécessairement un labyrinthe.
LarsH
1
@ m.buettner: J'imagine que les barres obliques sont des murs et que nous sommes supposés la visualiser comme s'il n'y avait aucun espace entre les lignes et entre les colonnes. Les caractères 2x2 en bas à gauche forment donc un losange (carré) totalement fermé.
LarsH
@LarsH ouais je le pensais bien. Cela soulève un autre point dans votre argument concernant la question du PO, à savoir que les gens devraient indiquer ce que sont le début et la fin. En outre, ce schéma ne permet même pas les jonctions. Vous ne pouvez avoir que ces carrés fermés ou ces chemins sinueux (qui peuvent aussi être des boucles fermées).
Martin Ender
+1 pour les graphiques améliorés et montrant la route. Je suppose que, compte tenu du nombre d'entrées et de sorties potentielles, la probabilité d'avoir "au moins un chemin d'accès d'au moins une entrée à au moins une sortie" est assez élevée!
LarsH
8

BBC BASIC, 18 octets

Une amélioration de la longueur de la version de la boucle infinie C64 à 23 octets de @nneonneo. La VDU envoie un seul caractère au contrôleur de la VDU: 2 + 1 * 45 = ASCII 47 /ou 2 + 2 * 45 = ASCII 92\

  VDU2+RND(2)*45:RUN

BBC BASIC, 35 octets / 107 à 95 octets

35 octets ne représentent que la dernière ligne, ce qui donne un labyrinthe de 25 lignes en 40 colonnes. MODE1 garantit qu'aucun espace supplémentaire n'est laissé entre les lignes. Le reste du programme est optionnel et améliore la mise en forme. Les instructions VDU23 redéfinissent la police des caractères 47 et 92 (8 octets formant un bitmap 8x8). J'inclus un pixel clair dans les quatre coins pour empêcher les lignes droites d'être pincées. L'effet secondaire de ceci est qu'un point apparaît dans les diamants vides. 107 octets au total, y compris 2 nouvelles lignes.

  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

Vous pouvez réduire ce programme à 95 octets en codant certains des codes de la VDU à 8 bits en petites valeurs finales de 16 bits (indiquées par un point-virgule après celles-ci au lieu d’une virgule) et en représentant l’instruction MODE sous la forme d’une paire de codes de la VDU, comme suit .

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

Sortie

Utilisation de BBC Basic pour Windows de bbcbasic.co.uk

Dernière ligne seulement, 35 octets

entrez la description de l'image ici

Programme entier, 107 95 octets

Comme je l'ai commenté sur la réponse de @ Brian, la barre oblique divise le carré en 2 triangles noirs, chacun ayant exactement 2 entrées / sorties. Cela garantit un chemin (trivial, non ramifié) de n'importe quel point du bord du labyrinthe à un autre point du bord du labyrinthe. Beaucoup d’entre elles sont très courtes, mais il semble toujours y en avoir quelques-unes longues. Bien sûr, au milieu du labyrinthe, il y a aussi des boucles.

Comme d’autres réponses ne l’ont pas mentionné, j’aimerais bien examiner les zones claires. Celles-ci sont délimitées par des zones sombres. Par conséquent, corollairement à la déclaration ci-dessus, une zone claire délimitée extérieurement par N zones sombres touche le bord du champ en N (exactement autant) points. Par conséquent, il existe des zones de lumière assez grandes qui forment des labyrinthes intéressants et ramifiés.

Dans l'exemple ci-dessous, vous pouvez voir la sortie brute (monochrome) de mon programme. En dessous (avec Windows Paint), j'ai coloré en bleu les deux zones sombres les plus longues. Ensuite, j'ai coloré la plus grande zone lumineuse en jaune et les deux zones délimitées en bleu en rouge et vert. Les labyrinthes jaunes, verts (et même les rouges) sont assez intéressants et non triviaux.

entrez la description de l'image ici

EDIT - Cueillette automatique des labyrinthes et sélection des débuts / fins

Pour une ligne supplémentaire (59 caractères), le programme peut sélectionner automatiquement jusqu'à 6 labyrinthes en choisissant des carrés au hasard et en remplissant les couleurs rouge, vert, jaune, bleu, magenta et cyan. Il ne trouve pas toujours un 6 entier, car s'il choisit un carré aléatoire qui a déjà été coloré, il ne fait rien.

Le reste du code ci-dessous choisit un début pour chaque couleur en balayant chaque colonne de haut en bas et de gauche à droite, puis en sélectionnant la première case rencontrée. Il choisit une fin en balayant dans la direction opposée.

Cela produit un ensemble de labyrinthes colorés et entrelacés. Parfois, ils sont tellement liés que les labyrinthes doivent traverser quelque part. Mais bien sûr, ils ne le font pas!

Code et sortie supplémentaires 59 + 187 = 246 caractères supplémentaires à ajouter à la fin du programme d'origine (pour une amélioration au-delà de la spécification de question)

  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)

entrez la description de l'image ici

Level River St
la source
7

C: 235 octets

#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++]);}

Remarque: dans ce qui précède, j'ai ajouté des nouvelles lignes pour l'adapter à la page. Sortie attendue (sur un terminal à 80 caractères):entrez la description de l'image ici

Je regrette que ce n'est pas un labyrinthe très difficile (en fait, il n'est pas nécessaire de revenir en arrière sur les anneaux intérieurs (et vous devriez être capable de trouver un chemin du périmètre au centre de manière triviale). Cependant, il a une belle implémentation du cercle de Bresenham algorithme de dessin à sa base.

imallett
la source
C'est un peu difficile de voir où vous pouvez passer et où vous ne pouvez pas. Je dois dire que j'ai préféré les tuyaux;) (à la fois pour ceci et pour ma soumission circulaire).
Martin Ender
@ m.buettner: Je suis en fait d'accord. Si vous modifiez le i+=2à i+=3, il sera peut-être plus clair ce qui se passe.
imallett
6

J'ai aidé mon enfant à faire cela, à apprendre un peu de programmation: http://jsfiddle.net/fs2000/4KLUC/34/ comment ça te plaît?

Giuseppe Strafforello
la source
17
Si vous pouvez adapter votre code à la publication, faites-le. En outre, incluez un en-tête comme #Language (s) - Bytecount. Si vous n'utilisez que des caractères ASCII dans votre code, vous pouvez obtenir un décompte sympa ici . Un résumé de ce que fait votre code, de toutes les idées que vous avez pu avoir ou de tout ce que vous avez fait pourrait être un ajout intéressant à votre message. À propos, Dark Vador rend très difficile de voir certaines des lignes. Enfin, bienvenue à Code Golf!
Rainbolt
Vous avez appris un peu de programmation avec vos enfants et j'ai appris un peu de golf. C'est mon premier golf et le résultat est encore assez long. Nombre d'octets: Original: 55 + 6822 = 6877. Un peu réorganisé : 39 + 3131 = 3170 Golfé : 39 + 1593 = 1632
BartekChom
6

Commodore 64 BASIC - 38 octets

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

Ce n'est pas mon invention, je ne fais que répéter un très beau programme court du temps passé. En fait, il existe un livre entier intitulé « 10 PRINT CHR$(205.5+RND(1)); : GOTO 10Célébrer ce code!

Vous pouvez voir le résultat sur cette vidéo YouTube ; voici un screencap:

Capture d'écran YouTube

Ici à cette question StackOverflow sont plus d'implémentations de ce programme générateur de labyrinthe. La mise en œuvre la plus courte du programme est le programme BASIC C64 de 23 octets suivant posté par l'auteur de cette question:

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

où les lettres minuscules sont entrées telles quelles et les lettres majuscules à l'aide de la touche Maj (elles ont une apparence différente sur un écran C64 réel).

Nneonneo
la source
N'est-ce pas exactement la même soumission de Brian? (juste un peu plus court) Et votre réponse de Bash l'est-elle? La question qui se pose est donc la suivante: un labyrinthe sans jonctions est-il toujours un labyrinthe?
Martin Ender
nneonneo, +1 pour l’attribution correcte et honnête de cette excellente idée. @ m.buettner La zone non imprimée produit des labyrinthes non ramifiés, comme vous le signalez. Cependant (et je suis étonné que personne d’autre ne l’ait encore montré), la zone imprimée forme des labyrinthes intéressants, non triviaux et ramifiés (voir ma réponse.) . Définir le début et la fin de ces labyrinthes diagonaux n’est pas facile.
Level River St
@ m.buettner 1. Le binaire x86 n'a que 10 octets au minimum. 2. Ceci est un algorithme bien rodé, et n’est pas du tout original, il n’était pas destiné à créer un labyrinthe soluble.
Isiah Meadows
5

Java: 700

Voici un sommateur mural récursif. L'algorithme est décrit sur ce site :

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;}}

Fondamentalement, il divise chaque rectangle en deux avec un mur (et un passage), puis en deux, etc. Il génère un labyrinthe "parfait" - un cycle sans cycles - qui a un chemin allant de point en point. Beaucoup d'impasses, donc ce n'est pas "trivial" dans tous les sens pour les plus grands labyrinthes.

Ainsi, l'entrée et la sortie peuvent être décidées arbitrairement. Si je dois en choisir un, il suffit de dire haut / gauche et bas / droite.

Il est dessiné au format ASCII double largeur, il est donc judicieux de diriger la sortie vers un fichier si vous utilisez un fichier de toute taille. Voici une console 20x20:

20x20

Et un 100x100 dans le bloc-notes ++ (je devais effectuer un zoom arrière pour avoir tout ça, alors c'est un peu ... petit ):

100x100

Code avec sauts de ligne:

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;
    }
}
Géobits
la source
2

ZX Basic - 281 caractères

Il s’agit plus d’un labyrinthe "correct", moins golfeur, mais plus mazier. Ce que l’on appelle l’algorithme du labyrinthe binaire, chaque cellule peut avoir une sortie en descente ou à droite, mais pas les deux. (Inclut maintenant les points de départ «S» et fin «E» marqués pour éviter de continuer tout droit d’un côté).

Le "::" est la méthode utilisée par ZXB pour saisir les caractères graphiques Spectrum dans un fichier texte, ce qui équivaut à un caractère de bloc vendu.

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"

Labyrinthe

Brian
la source
2
Non, je voulais dire en fait que vous devriez échanger le début et la fin (début en bas à droite, fin en haut à gauche). En l'état actuel des choses, en raison des règles, il suffit de descendre tout le temps pour atteindre la fin.
Martin Ender
1
Même si le début et la fin sont inversés, le labyrinthe a la propriété (peut-être intéressante) que le chemin correct ne fera que monter et descendre. Cependant, le labyrinthe n'est plus anodin, car il existe de nombreux points sur lesquels vous pouvez aller de deux manières.
Kevin - Réintégrer Monica le
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;}

Voici à quoi ça ressemble:

Labyrinthe

Remarque: cette solution est inspirée du jeu non approuvé du niveau 8: dans les bois.

Mhmd
la source