Print a random maze

19

6

Write a program that generates and prints a random maze using the algorithm of your choice. The maze should be different for multiple runs of the program. Height and width are given as command line arguments. Use | for vertical wall, - for horizontal wall and + for corner. The maze is bounded by walls and the entrances are marked by missing wall. The maze contains a treasure # which must be reachable from at least one entrance.

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

Alexandru

Posted 2011-01-30T12:42:18.280

Reputation: 5 485

Interesting challenge. I'll put something together later today when I have access to a usable Java IDE. – SuperJedi224 – 2015-08-04T16:56:53.417

must there be at least 1 path open from the entrance to treasure? or we don't have to consider this? – mauris – 2011-03-21T11:48:19.577

+1 Great Question. A few points though. 1: How is the exit marked? Is it a symbol like * or is there two separate entrances? 2: You should probably specify that the exit must be reachable. – snmcdonald – 2011-01-30T19:50:42.760

1@snmcdonald: let's make it fun and add a treasure :). – Alexandru – 2011-01-30T20:36:16.370

1The puzzle type is unspecified here. I see that people answered it as if it were a [code-golf]. Was that the intent? If so, please tag it as such? – dmckee --- ex-moderator kitten – 2011-06-01T13:25:36.190

2I can see a follow up golf, about solving them... :) – st0le – 2011-02-01T06:22:50.197

@st0le: I already have some ideas. Mail me if you want to discuss. – Alexandru – 2011-02-01T17:48:15.200

Answers

5

I think this technically isn't a maze generator, but it creates a maze like result: https://gist.github.com/803450.

Some horrible code in there I know, and it only works less than half the time, and the result doesn't look quite right to do with walls sticking out from other walls. But its close enough that I can't be bothered fixing the rest.

Some example output:

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

Nemo157

Posted 2011-01-30T12:42:18.280

Reputation: 1 891

1Nice idea. Extra points if you fix it ;) – Alexandru – 2011-02-02T01:03:24.173

This was just a quick rip out and change of output for an algorithm I used for generating a maze for one of my uni assignments. The actual algorithm is mainly stolen from a blog post by CHEVYRAY. I might get around to fixing it up this weekend, I'm not sure if the output format will entirely work since it isn't a true maze, but I'll try and get it as close as possible while looking good.

– Nemo157 – 2011-02-02T09:27:15.563

Seems a very good maze to me. – Alexandru – 2011-02-02T12:18:40.530

8

Python, 375 characters

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

This generates a maze with one entrance and a randomly placed treasure. The maze is a simple binary tree maze.

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

Keith Randall

Posted 2011-01-30T12:42:18.280

Reputation: 19 865

Maybe it was intended, but the top row (just under the wall) is always a long corridor. – Alexandru – 2011-01-31T00:53:59.947

Yes, and the leftmost column is always a long corridor as well. This is a property of the type of maze I'm generating. – Keith Randall – 2011-01-31T05:03:17.160

Oh. The mazes are very nice though :). – Alexandru – 2011-01-31T12:24:52.150

6

Ruby 1.9.2p136 : 90

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

Output

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

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

Hey, no one said it had to be a good maze. OK, OK, I'll make a real one now.

Mike Bethany

Posted 2011-01-30T12:42:18.280

Reputation:

Good, but make sure it respects the protocol (height and width from command line, maze printed to stdout). – Alexandru – 2011-01-31T12:24:05.960

Actually it doesn't say anything about stdout (that's also not a reasonable stipulation because someone might be using a language that doesn't print to stdout) and it's commonly accepted that inputs are to a function/method. To the person down voting this, it solves the problem as specified so don't hate the mazer hate the maze. – None – 2011-01-31T16:04:16.617

Not really as long as it specified in the question. See http://meta.codegolf.stackexchange.com/questions/13/what-input-methods-should-we-allow-for-code-golfs . Moreover, unlike JavaScript Ruby supports argument reading and writing to standard output. Your solution is cheating compared to others who solved the problem the right way.

– Alexandru – 2011-01-31T16:34:33.573

Cannot edit. I meant 'incomplete' not 'cheating'. I like the idea of the maze. – Alexandru – 2011-01-31T16:40:45.173

Then the other languages have to include the code it takes to call them or include #!/usr/bin/env python, for example, in their code. As I said I'll write a real solution too, this was just pointing out the poor quality of the question itself (and many others) and demonstrates we need to have better guidelines. And finally pointing to a question does not make the answer to the question the actual rules for the site. But fine, here's your new version... – None – 2011-01-31T19:26:24.073

Please let me know how you think the question can be improved. – Alexandru – 2011-01-31T21:01:31.937

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

To Test:

#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

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

snmcdonald

Posted 2011-01-30T12:42:18.280

Reputation: 641

This is a [tag:code-challenge], not a [tag:code-golf]. Why the barely readable code? – Braden Best – 2014-02-17T20:42:11.757

-1. Not only is this code obfuscated, but there are no clear instructions on how this should be compiled, and how the two blocks of code should be implemented. Usage instructions are sparse, if not entirely missing. It's obvious that your answer is a code-golf. But the question isn't. So the code should be readable, and self-contained for easy copy/paste/compile, so that others can verify that it indeed works without having to decipher how you got the code to work in the first place. – Braden Best – 2014-02-17T21:25:26.050

0

Here's a simple java solution:

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

Some sample results:

3x3:

+ +
|#|
+-+

4x4:

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

4x5:

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

5x5:

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

5x8:

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

8x15:

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

SuperJedi224

Posted 2011-01-30T12:42:18.280

Reputation: 11 342