Надрукуйте випадковий лабіринт


19

Напишіть програму, яка генерує та друкує випадковий лабіринт, використовуючи алгоритм на ваш вибір. Лабіринт повинен бути різним для декількох запусків програми. Висота та ширина наведені як аргументи командного рядка. Використовуйте |для вертикальної стіни, -для горизонтальної стіни та +для кутового. Лабіринт обмежений стінами, а входи позначені відсутніми стінами. У лабіринті є скарб, #який повинен бути доступний хоча б з одного входу.

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

+1 Велике запитання. Кілька пунктів, хоча. 1: Як маркується вихід? Це символ на кшталт *або є два окремі входи? 2: Напевно, ви повинні вказати, що вихід повинен бути доступним.
snmcdonald

1
@snmcdonald: давайте розважимось та додамо скарб :).
Олександру

2
Я бачу подальший гольф щодо їх вирішення ... :)
st0le

@ st0le: У мене вже є кілька ідей. Надішліть мені пошту, якщо хочете обговорити.
Олександру

1
Тип головоломки тут не визначений. Я бачу, що люди відповіли на це так, ніби це був [код-гольф]. Це був намір? Якщо так, будь ласка, позначте це як таке?
dmckee

Відповіді:


5

Я думаю, що це технічно не генератор лабіринтів, але він створює результат, подібний до лабіринту: https://gist.github.com/803450 .

Я знаю якийсь жахливий код у ньому, і він працює лише менше половини часу, і результат виглядає не так правильно, як це стосується стін, що стирчать з інших стін. Але його досить близько, що я не можу заважати фіксувати решту.

Деякі приклади виводу:

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

1
Хороша ідея. Додаткові бали, якщо ви виправите це;)
Олександру

Це було просто швидке вимкнення та зміна виводу для алгоритму, який я використовував для створення лабіринту для одного з моїх універсальних завдань . Справжній алгоритм в основному викрадений з публікації блогу CHEVYRAY . Я можу обійтись, щоб виправити це в ці вихідні, я не впевнений, чи буде вихідний формат повністю працювати, оскільки це не справжній лабіринт, але я спробую наблизити його якомога ближче, добре виглядаючи.
Nemo157

Здається мені дуже хороший лабіринт.
Олександру

8

Пітон, 375 символів

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

Це породжує лабіринт з одним входом і випадково розміщеним скарбом. Лабіринт - це простий двійковий лабіринт дерева .

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

Можливо, це було призначено, але верхній ряд (просто під стіною) - це завжди довгий коридор.
Олександру

Так, і сама ліва колона - це завжди довгий коридор. Це властивість типу лабіринту, який я генерую.
Кіт Рендалл

Ой. Лабіринти дуже приємні, хоча :).
Олександру

6

Рубін 1.9.2p136: 90

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

Вихідні дані

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

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

Гей, ніхто не сказав, що це повинен бути хороший лабіринт. Гаразд, добре, зараз я зроблю справжній.


Добре, але переконайтеся, що він дотримується протоколу (висота та ширина від командного рядка, лабіринт, надрукований до stdout).
Олександру

Насправді це нічого не говорить про stdout (це також не є розумним умовою, оскільки хтось може використовувати мову, яка не друкує до stdout), і загальновизнано, що вхідні дані є функцією / методом. Для людини, яка голосує за це, вона вирішує задачу, як зазначено, тому не ненавидьте, коли мазер ненавидить лабіринт.

Не дуже, доки це визначено у питанні. Див meta.codegolf.stackexchange.com/questions/13 / ... . Більше того, на відміну від JavaScript, Ruby підтримує читання та запис аргументів до стандартного виводу. Ваше рішення обманює порівняно з іншими, які вирішили проблему правильним шляхом.
Олександру

Неможливо редагувати Я мав на увазі «неповне», а не «обман». Мені подобається ідея лабіринту.
Олександру

Тоді інші мови повинні включати код, необхідний для їх виклику, або включати #!/usr/bin/env python, наприклад, у свій код. Як я вже говорив, я теж напишу справжнє рішення, це лише вказувало на низьку якість самого питання (та багатьох інших) і демонструє, що нам потрібно мати кращі рекомендації. І, нарешті, вказівка ​​на запитання не дає відповіді на питання фактичними правилами для сайту. Але чудово, ось ваша нова версія ...

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

Перевіряти:

#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

3х3

+ +
| # |
+ - +

7х8

+ - + - - +
| |
+ + - + - +
| |
| + - + - +
| | № |
+ - + - + - +

18х20

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

Це виклик коду , а не гольф коду . Чому ледь читабельний код?
Бреден Найкращий

-1. Цей код не тільки затуманений, але й немає чітких інструкцій щодо того, як це слід скласти, і як два блоки коду мають бути реалізовані. Інструкція з використання є рідкою, якщо не повністю відсутня. Очевидно, що ваша відповідь - кодовий гольф. Але питання не в цьому . Таким чином, код повинен бути читабельним і самостійним для легкої копіювання / вставки / компіляції, щоб інші могли переконатися, що він справді працює, не розшифровуючи, як ви змусили код працювати в першу чергу.
Бреден Кращий

0

Ось просте рішення Java:

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

Деякі результати вибірки:

3x3:

+ +
|#|
+-+

4x4:

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

4x5:

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

5x5:

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

5x8:

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

8x15:

+---- ----+---+
|         |   |
|         |   |
|         |   |
|             |
| #|      |   |
|         |   |
+---------+---+
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.