Imprimer un labyrinthe aléatoire


19

Écrivez un programme qui génère et imprime un labyrinthe aléatoire en utilisant l'algorithme de votre choix. Le labyrinthe doit être différent pour plusieurs exécutions du programme. La hauteur et la largeur sont données comme arguments de ligne de commande. Utilisation |pour mur vertical, -pour mur horizontal et +pour coin. Le labyrinthe est délimité par des murs et les entrées sont marquées par un mur manquant. Le labyrinthe contient un trésor #qui doit être accessible depuis au moins une entrée.

$ python2 random-maze.py 4 5
+-+-+
  |#|
|   |
+---+

+1 Grande question. Quelques points cependant. 1: Comment est marquée la sortie? Est-ce un symbole *ou y a-t-il deux entrées distinctes? 2: Vous devez probablement spécifier que la sortie doit être accessible.
snmcdonald

1
@snmcdonald: rendons-le amusant et ajoutons un trésor :).
Alexandru

2
Je peux voir un golf de suivi, pour les résoudre ... :)
st0le

@ st0le: J'ai déjà quelques idées. Envoyez-moi un mail si vous souhaitez en discuter.
Alexandru

1
Le type de puzzle n'est pas spécifié ici. Je vois que les gens y ont répondu comme s'il s'agissait d'un [code-golf]. Était-ce l'intention? Si oui, veuillez le marquer comme tel?
dmckee

Réponses:


5

Je pense que techniquement, ce n'est pas un générateur de labyrinthe, mais cela crée un résultat semblable à un labyrinthe: https://gist.github.com/803450 .

Je connais un code horrible, et cela ne fonctionne que moins de la moitié du temps, et le résultat ne semble pas tout à fait correct avec des murs qui dépassent des autres murs. Mais c'est assez proche pour que je ne puisse pas être gêné de réparer le reste.

Un exemple de sortie:

→ ruby random-maze.rb 30 30
+----+-+-----------++-+----+
|    + |           ++ |    |
++  +  | ++ ++   +    + ++ ++
|  ++ ++ |  |    +---+  +   |
| +      | +| +   +++  +  + |
|   +   +| +| +-+  |   + +  |
|        +  +    + + ++  |+ |
| + ++ +  ++   + |  +   ++| |
| |  | ++  + +----+ + +-+ | |
| +  |  +-+  |+        |  | |
|   +-+  +| ++  ++ + + |  | |
| ++   +  + |  ++|   + | ++ |
|  + + + +  +---++-+   +++  |
| +  |  +| +    |  ++   |   |
| | +++ +| + ++ +--+  + |---+
|#+ | |  |   +++     +  +   |
++  | ++ +-+  ++ +--+  +  + |
|  ++  |    +     ++| +  ++ |
| ++   +--------+  +| + +   |
| |     |      +++  |  +  +-+
| |     | +--+  |++ |+ | ++
| |     |  +--+ | | || |  |
| |     +-+     +-+ |+ |+ |
| | +---+   ++      +  |  |
| +-|     +    +      ++ ++
|   +       ++   +---+   |
|              ++   +  +-+
|                 +   ++
+-+ +-------------+---+

1
Bonne idée. Des points supplémentaires si vous le corrigez;)
Alexandru

Ce n'était qu'une extraction rapide et un changement de sortie pour un algorithme que j'ai utilisé pour générer un labyrinthe pour l'une de mes affectations uni . L'algorithme réel est principalement volé dans un article de blog de CHEVYRAY . Je pourrais essayer de le réparer ce week-end, je ne sais pas si le format de sortie fonctionnera entièrement car ce n'est pas un vrai labyrinthe, mais je vais essayer de le rapprocher le plus possible tout en ayant l'air bien.
Nemo157

Cela me semble un très bon labyrinthe.
Alexandru

8

Python, 375 caractères

import random,sys
H,V=map(int,sys.argv[1:])
H-=1
V-=1
b,h,v,p=' -|+'
M=H/2*h
n=random.randint(1,(H/2)*(V/2-1))
for i in range(V/2):
 e=s=t='';N=v
 for j in range(H/2):
  if i and(random.randint(0,1)or j==0):s+=N+b;t+=v;N=v;M=M[1:]+p
  else:s+=M[0]+h;t+=b;N=p;M=M[1:]+h
  n-=1;t+=' #'[n==0]
 if H&1:s+=s[-1];t+=b;e=h
 print s+N+'\n'+t+v
if V&1:print t+v
print h.join(M)+e+h+p

Cela génère un labyrinthe avec une entrée et un trésor placé au hasard. Le labyrinthe est un simple labyrinthe d'arbres binaires .

$ ./maze.py 15 15
--------------+
              |
| | ----------+
| |           |
| +-----+ | --+
|       | |   |
| --+ --+ +---+
|   |   |     |
| --+-+ +---+ |
|     |     | |
| --+ +-+ --+ |
|   |   |   |#|
| | | --+ --+-+
| | |   |     |
+-+-+---+-----+

Peut-être que c'était prévu, mais la rangée du haut (juste sous le mur) est toujours un long couloir.
Alexandru

Oui, et la colonne la plus à gauche est toujours aussi un long couloir. Il s'agit d'une propriété du type de labyrinthe que je génère.
Keith Randall

Oh. Les labyrinthes sont très bien quand même :).
Alexandru

6

Rubis 1.9.2p136: 90

eval ARGV[0]
z=[l="+"+"-"*@w+"+"]
@h.times{z<<"|"+" "*@w+"|"}
z[rand(@h)+1]="|#"
puts z<<l

Production

$> ruby maze.rb "@h=8;@w=8;"

+------+
|      |
|      |
|      |
|      |
|#
|      |
+------+

Hé, personne n'a dit que ça devait être un bon labyrinthe. OK, OK, je vais en faire un vrai maintenant.


Bon, mais assurez-vous qu'il respecte le protocole (hauteur et largeur depuis la ligne de commande, labyrinthe imprimé sur stdout).
Alexandru

En fait, cela ne dit rien sur stdout (ce n'est pas non plus une stipulation raisonnable car quelqu'un peut utiliser un langage qui n'imprime pas sur stdout) et il est communément admis que les entrées sont destinées à une fonction / méthode. Pour la personne qui vote, cela résout le problème comme spécifié, alors ne détestez pas le mazer déteste le labyrinthe.

Pas vraiment tant qu'il est précisé dans la question. Voir meta.codegolf.stackexchange.com/questions/13/… . De plus, contrairement à JavaScript, Ruby prend en charge la lecture et l'écriture d'arguments sur une sortie standard. Votre solution est de tricher par rapport à d'autres qui ont résolu le problème de la bonne façon.
Alexandru

Impossible de modifier. Je voulais dire «incomplet» et non pas «tricher». J'aime l'idée du labyrinthe.
Alexandru

Ensuite, les autres langues doivent inclure le code nécessaire pour les appeler ou inclure #!/usr/bin/env python, par exemple, dans leur code. Comme je l'ai dit, j'écrirai également une vraie solution, cela ne faisait que souligner la mauvaise qualité de la question elle-même (et bien d'autres) et démontre que nous devons avoir de meilleures directives. Et enfin pointer vers une question ne fait pas la réponse à la question des règles réelles du site. Mais bien, voici votre nouvelle version ...

3

C 844

#include <stdlib.h>
#include <time.h>
h,w,*m,y,x,z;d(t,b,l,r){int i=b-t,j=r-l;if(i>1&&j>1){i=(rand()%--i)|1;j=(rand()%--j)|1;z=rand()%4;x=rand()%i+t;x|=1;for(y=t;y<i+t;y++)if(y!=x||!z)m[y*w+j+l]=124;x=rand()%(b-i-t)+i+t;x|=1;for(y=t+i;y<b+1;y++)if(y!=x||!(z-1))m[y*w+j+l]=124;y=rand()%j+l;y|=1;for(x=l;x<j+l;x++)if(y!=x||!(z-2))m[(i+t)*w+x]=45;y=rand()%(r-j-l)+j+l;y|=1;for(x=l+j;x<r+1;x++)if(y!=x||!(z-3))m[(i+t)*w+x]=45;m[(i+t)*w+j+l]=43;m[(t-1)*w+l+j]=43;m[(b+1)*w+j+l]=43;m[(i+t)*w+l-1]=43;m[(i+t)*w+r+1]=43;d(t,t+i-1,l,l+j-1);d(t+i+1,b,l,l+j-1);d(t,t+i-1,l+j+1,r);d(t+i+1,b,l+j+1,r);}}main(int c,char**v){h=atoi(v[1]),w=atoi(v[2]),m=calloc(h*w,4);srand(time(0));while(y<h){while(x<w){m[y*h+x]=(!y||y==h-1)?(!x||x==w-1)?43:45:(!x||x==w-1)?124:32;x++;}y++;x=0;}d(1,h-2,1,w-2);z=rand()%(w-2);z|=1;m[z]=32;z=rand()%(w-2);z|=1;m[h*(w-2)+z]=35;}

Tester:

#include <stdio.h>//beginning
for(y=0;y<h;y++){for(x=0;x<w;x++){putchar(m[y*h+x]);}putchar('\n');}getchar();//end

3x3

+ +
| # |
+ - +

7x8

+ - + - - +
| |
+ + - + - +
| |
| + - + - +
| | # |
+ - + - + - +

18x20

+ - + - + + --- + --- + - + - +
| | | | |
| + + + - + --- + + - +
| | | |
+ + + - + --- + - + - + - +
| | | |
+ - + + - + - + - + --- + - + - +
| | | | | |
| + + + + - + - - + |
| | | | |
| | | + - + - + ---- + |
| | | | |
+ + + - + - + - + - - + - +
| | | | |
| + + - + - + - - + |
| | | | |
| | | | # | | |
+ - + - + - + --- + ----- + - +

C'est un défi de code , pas un golf de code . Pourquoi le code à peine lisible?
Braden Best

-1. Non seulement ce code est obscurci, mais il n'y a pas d'instructions claires sur la façon dont cela doit être compilé et comment les deux blocs de code doivent être implémentés. Les instructions d'utilisation sont rares, sinon entièrement manquantes. Il est évident que votre réponse est un code-golf. Mais la question ne l'est pas . Le code doit donc être lisible et autonome pour un copier / coller / compiler facile, afin que les autres puissent vérifier qu'il fonctionne effectivement sans avoir à déchiffrer comment vous avez fait fonctionner le code en premier lieu.
Braden Best

0

Voici une solution java simple:

import java.util.*;

public class MazeGen {
    public static void main(String[]a){
        int w,l;
        Random rand=new Random(System.currentTimeMillis()%1000+System.nanoTime());
        if(a.length==2){
            w=Integer.parseInt(a[0]);
            l=Integer.parseInt(a[1]);
        }else{
            System.out.println("No command line arguments, taking from STDIN.");
            Scanner input=new Scanner(System.in);
            w=input.nextInt();
            l=input.nextInt();
            input.close();
        }
        char[][]maze=new char[w][l];
        for(int x=0;x<w;x++){
            for(int y=0;y<l;y++){
                maze[x][y]=' ';
            }
        }
        for(int x=0;x<w;x++){
            maze[x][0]=maze[x][l-1]='|';
        }
        for(int y=0;y<l;y++){
            maze[0][y]=maze[w-1][y]='-';
        }
        maze[0][0]=maze[w-1][0]=maze[w-1][l-1]=maze[0][l-1]='+';
        int dor=1+rand.nextInt(l-2);
        maze[0][dor]=' ';
        int tx=2+rand.nextInt(w-3),ty=1+rand.nextInt(l-2);
        maze[tx][ty]='#';
        if(ty<dor-1){
            maze[tx][ty+1]='|';
            if(tx==w-2){
                maze[tx+1][ty+1]='+';
            }
            if(tx==1){
                maze[0][ty+1]='+';
            }
        }
        if(ty>dor+1){
            maze[tx][ty-1]='|';
            if(tx==w-2){
                maze[tx+1][ty-1]='+';
            }
            if(tx==1){
                maze[0][ty-1]='+';
            }
        }
        if(ty==dor&&tx>3&&(maze[tx][ty+1]==' '||maze[tx][ty-1]==' ')){
            maze[tx-1][ty]='-';
        }
        if(dor>5){
            int z=2+rand.nextInt(dor-3);
            int q=1+rand.nextInt(w-3);
            for(int i=0;i<w;i++){
                if(i==0||i==w-1){
                    maze[i][z]='+';
                }else if(i!=q&&maze[i][z]==' '){
                    maze[i][z]='|';
                }
            }

        }
        if(l-dor>5){
            int z=dor+2+rand.nextInt(l-dor-3);
            int q=1+rand.nextInt(w-3);
            for(int i=0;i<w;i++){
                if(i==0||i==w-1){
                    maze[i][z]='+';
                }else if(i!=q&&maze[i][z]==' '){
                    maze[i][z]='|';
                }
            }

        }
        for(char[]row:maze){
            System.out.println(row);
        }
    }
}

Quelques exemples de résultats:

3x3:

+ +
|#|
+-+

4x4:

+ -+
| #|
|  |
+--+

4x5:

+-+ +
|#| |
|   |
+---+

5x5:

+ --+
|   |
|   |
| |#|
+-+-+

5x8:

+ --+--+
|   |  |
|      |
| # |  |
+---+--+

8x15:

+---- ----+---+
|         |   |
|         |   |
|         |   |
|             |
| #|      |   |
|         |   |
+---------+---+
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.