User avatar
davef21370
Posts: 897
Joined: Fri Sep 21, 2012 4:13 pm
Location: Earth But Not Grounded

Minecraft Maze Generator

Fri Feb 15, 2013 5:24 pm

Minecraft maze creation code, a bit rough and far from perfect but do with it what you will.

Cheers.
Dave.

Code: Select all

# Quick rough & ready maze generator for Minecraft Pi edition.
# Dave Finch 2013

import minecraft, block
import sys, random
from random import randint as rand

# Connect to Minecraft.
try:
    mc = minecraft.Minecraft.create()
except:
    print "Cannot connect to Minecraft."
    sys.exit(0)

# Create a function for picking a random direction.
def randDir():
    r = rand(0,3)
    if r == 0: rv = (0,-1) # Up.
    if r == 1: rv = (0,1) # Down.
    if r == 2: rv = (-1,0) # Left.
    if r == 3: rv = (1,0) # Right.
    return rv

# Create a function to initialize the maze.
# w and h are the width and height respectively.
def initMaze(w,h):
    global maze,spl

    # Create a 2 dimensional array.
    maze = [[0]*h for x in range(w)]

    # Create four walls around the maze.
    # 1=wall, 0=walkway.
    for x in range(0,w):
        maze[x][0] = maze[x][h-1] = 1
        makeWall(ppos.x+x,ppos.z+0)
        makeWall(ppos.x+x,ppos.z+h-1)
    for y in range(0,mazeYSize):
        maze[0][y] = maze[w-1][y] = 1
        makeWall(ppos.x,ppos.z+y)
        makeWall(ppos.x+w-1,ppos.z+y)

    # Make every other cell a starting point.
    # 2=starting point.
    # Also create a list of these points to speed up the main loop.
    spl = []
    for y in range(2,h-2,2):
        for x in range(2,w-2,2):
            maze[x][y] = 2
            spl.append((x,y))
    # Shuffle the list of points and we can choose a random point by
    # simply "popping" it off the list.
    random.shuffle(spl)

def makeWall(x,z):
    mc.setBlock(x,ppos.y,z,block.STONE)
    mc.setBlock(x,ppos.y+1,z,block.STONE)
    mc.setBlock(x,ppos.y+2,z,block.STONE)

# Define the X and Y size of the maze including the outer walls.
# These values aren't checked but must be positive odd integers above 3.
mazeXSize = 35
mazeYSize = 35

# Set the maximum length of a wall.
maxWallLen = 1

# Find position of player and set base of maze 3 blocks lower.
ppos = mc.player.getPos()
ppos.y -= 3

# Clear an area for the maze.
for x in range(0,mazeXSize-1):
    for z in range(mazeYSize-1):
        mc.setBlock(ppos.x+x,ppos.y,ppos.z+z,block.STONE)
        for y in range(1,5):
            mc.setBlock(ppos.x+x,ppos.y+y,ppos.z+z,block.AIR)

# Create an empty maze.
initMaze(mazeXSize,mazeYSize)

# Loop until we have no more starting points (2's in the empty maze)
while filter(lambda x: 2 in x, maze):
    # Get the X and Y values of the first point in our randomized list.
    rx = spl[0][0]
    ry = spl[0][1]
    # Pop the first entry in the list, this deletes it and the rest move down.
    spl.pop(0)
    # Check to see if our chosen point is still a valid starting point.
    ud = False
    if maze[rx][ry] == 2:
        ud = True
        # Pick a random wall length up to the maximum.
        rc = rand(0,maxWallLen)
        # Pick a random direction.
        rd = randDir()
        fc = rd
        loop = True
        while loop:
            # Look in each direction, if the current wall being built is stuck inside itself start again.
            if maze[rx][ry-2] == 3 and maze[rx][ry+2] == 3 and maze[rx-2][ry] == 3 and maze[rx+2][ry] == 3:
                #
                # Code to clear maze area required
                #
                initMaze(mazeXSize,mazeYSize)
                break
            # Look ahead to see if we're okay to go in this direction.....
            cx = rx + (rd[0]*2)
            cy = ry + (rd[1]*2)
            nc = maze[cx][cy]
            if nc != 3:
                for i in range(0,2):
                    maze[rx][ry] = 3
                    makeWall(ppos.x+rx,ppos.z+ry)
                    rx += rd[0]
                    ry += rd[1]
            # .....if not choose another direction.
            else: rd = randDir()
            # If we hit an existing wall break out of the loop.
            if nc == 1: loop = False
            # Update our wall length counter. When this hits zero pick another direction.
            # This also makes sure the new direction isn't the same as the current one.
            rc -= 1
            if rc <= 0:
                rc = rand(0,maxWallLen)
                dd = rd
                de = (fc[0]*-1,fc[1]*-1)
                while dd == rd or rd == de:
                    rd = randDir()
    # The latest wall has been built so change all 3's (new wall) to 1's (existing wall)
    if ud:
        for x in range(0,mazeXSize):
            for y in range(0,mazeYSize):
                if maze[x][y] == 3: maze[x][y] = 1
    
Apple say... Monkey do !!

User avatar
malakai
Posts: 1382
Joined: Sat Sep 15, 2012 10:35 am

Re: Minecraft Maze Generator

Fri Feb 15, 2013 6:17 pm

Thank you can't wait to give it a try Minecraft is about the best hope I have for my 14 year old to really get into programming.
http://www.raspians.com - always looking for content feel free to ask to have it posted. Or sign up and message me to become a contributor to the site. Raspians is not affiliated with the Raspberry Pi Foundation. (RPi's + You = Raspians)

User avatar
davef21370
Posts: 897
Joined: Fri Sep 21, 2012 4:13 pm
Location: Earth But Not Grounded

Re: Minecraft Maze Generator

Fri Feb 15, 2013 6:24 pm

14 is a good age to get into programming and this version of Minecraft for the Pi is an ideal way to get them interested. To be honest this code isn't the best way into it as it's scruffy but it's a decent example of what's possible.
The beauty of the Pi edition is the simplicity of manipulating blocks, with a few nested loops and a little imagination anything is possible !

Dave.
Apple say... Monkey do !!

pygmy_giant
Posts: 1562
Joined: Sun Mar 04, 2012 12:49 am

Re: Minecraft Maze Generator

Fri Feb 15, 2013 7:04 pm

This is an interesting problem - the challenge is to come up with a configuration of cells such that there are no walls/passageways thicker than one cell and no inaccessable areas. I tried something similar using C. The algorithm I came up with was:

1) create an array (can even be 3d)
2) Brick it all up (populate with value 1)
3) Use nested loops to scan through all cells within the border starting with any corner.
4) Whilst doing this ascertain whether changing the state of any bricked up cell (value 1) to an empty one (value 0) would create a passageway of more than 1 cell thickness.
5) If not then randomly decide whether to change the state of that block according to a 50% probability
6) Once all the cells have been examined and possibly changed, scan through the array again until the first empty cell is found.
7) Asssign this a value different to that belonging to a walled or empty cell to represent 'water' (2)
8) Repeatedly scan through the array 'flooding' all empty cells adjecent to watery ones until no further flooding is possible.
9) Scan through the array again to check for air pockets (inaccessible areas) or walls/passageways thicker than one block.
10) If none are found then end - the maze is complete!
11) Otherwise drain (remove water) and go to step 3)

This method was slow for large arrays, but effective.

I think there is now a random number generator in the Raspbian kernel based upon thermal noise that could be handy.

mcpipy
Posts: 5
Joined: Wed Feb 13, 2013 1:21 am

Re: Minecraft Maze Generator

Sat Feb 16, 2013 1:44 pm

Thanks for sharing this! I've grabbed some pictures and shared it out on the blog @ http://mcpipy.wordpress.com/2013/02/16/maze/

User avatar
davef21370
Posts: 897
Joined: Fri Sep 21, 2012 4:13 pm
Location: Earth But Not Grounded

Re: Minecraft Maze Generator

Sat Feb 16, 2013 2:01 pm

Thanks mcpipy, I've just done a quick video of it in action....
http://www.youtube.com/watch?v=AwadhoFIjRY
and I need to make a change, instead of using setBlock to clear an area before building the maze I could have used setBlocks to speed things up enormously, live and learn eh?

Dave.
Apple say... Monkey do !!

User avatar
malakai
Posts: 1382
Joined: Sat Sep 15, 2012 10:35 am

Re: Minecraft Maze Generator

Sun Feb 17, 2013 7:05 am

Got it all working thank you all. One question is network play enabled? Can't find a thread that says yes or no it just says looking for game? Do I need a server? Help 2 kids want to destroy each other's world and well anarchy at their age burns a lot of that testosterone that seems to build up at times.
http://www.raspians.com - always looking for content feel free to ask to have it posted. Or sign up and message me to become a contributor to the site. Raspians is not affiliated with the Raspberry Pi Foundation. (RPi's + You = Raspians)

User avatar
malakai
Posts: 1382
Joined: Sat Sep 15, 2012 10:35 am

Re: Minecraft Maze Generator

Sun Feb 17, 2013 7:18 am

Oh and anyone wanna help with a project similar to cheerlights. Basically once they get the whole network thing going a script that when you tweet snow it snows in everyone's Minecraft, or Night, or, Cheerlights in and of itself? Is it possible I think it could be. I will host whatever I have unlimited bandwidth and will be posting a server in a Datacenter where I work. I will admit I am so busy I get overwhelmed but now I got my sons going I am putting their inheritance (10$ USD) on the line :) if they don't do something cool with all this.
http://www.raspians.com - always looking for content feel free to ask to have it posted. Or sign up and message me to become a contributor to the site. Raspians is not affiliated with the Raspberry Pi Foundation. (RPi's + You = Raspians)

pygmy_giant
Posts: 1562
Joined: Sun Mar 04, 2012 12:49 am

Re: Minecraft Maze Generator

Sun Feb 17, 2013 1:42 pm

Good work - my 8 year old will enjoy playing with this maze n Minecraft.

Sorry to interrupt - I decided my agorith above is rubbish and as I do not understand Python I wrote my own program in C:

Code: Select all

#include <stdio.h>
#include <stdlib.h>



/* sets size of maze */
#define X_SIZE 30
#define Y_SIZE 30



/* generated map */
unsigned char maze[X_SIZE][Y_SIZE];



/* function declarations */
void initialise();
unsigned char random_value(unsigned char range);
unsigned char grow();
void display();
unsigned char adjacent_neighbours(unsigned char x, unsigned char y);
unsigned char diagonal_neighbours(unsigned char x, unsigned char y);
unsigned char can_grow(unsigned char x, unsigned char y);
unsigned char is_odd(unsigned char to_test);



/* main program loop */
int main(int argc, char **argv)
{
initialise();
while(grow()>0)
{
/* grows walls until no more room */
}
display();
return 0;
}



/* add border and randomises */
void initialise()
{
unsigned char x;
unsigned char y;
unsigned char x_max;
unsigned char y_max;
srand(time(0));
x_max=X_SIZE-1;
y_max=Y_SIZE-1;
y=0;
while(y<Y_SIZE)
{
x=0;
while(x<X_SIZE)
{
if(x==0 || y==0 || x==x_max || y==y_max)
{
maze[x][y]=1;
}
x++;
}
y++;
}
}



/* display maze */
void display()
{
unsigned char x;
unsigned char y;
y=0;
while(y<Y_SIZE)
{
x=0;
printf("\n ");
while(x<X_SIZE)
{
if(maze[x][y]==1)
{
printf("#");
}
else
{
printf(" ");
}
x++;
}
y++;
}
}



/* grows walls */
unsigned char grow()
{
unsigned char x;
unsigned char y;
unsigned char x_max;
unsigned char y_max;
unsigned char growth;
growth=0;
x_max=X_SIZE-1;
y_max=Y_SIZE-1;
y=1;
while(y<y_max)
{
x=1;
while(x<x_max)
{
if(maze[x][y]==0 && can_grow(x,y)==1)
{
if(random_value(2)==0)
{
maze[x][y]=1;
}
growth++;
}
x++;
}
y++;
}
return growth;
}



/* checks that placing a block will not obstruct or clash */
unsigned char can_grow(unsigned char x, unsigned char y)
{
unsigned char diag_count;
unsigned char left_c;
unsigned char right_c;
unsigned char top_c;
unsigned char bottom_c;

diag_count=diagonal_neighbours(x,y);
if(adjacent_neighbours(x,y)==1 && diag_count<=2)
{
left_c=(maze[x][y-1]+maze[x-1][y-1]+maze[x-1][y]+maze[x-1][y+1]+maze[x][y+1]);
right_c=(maze[x][y-1]+maze[x+1][y-1]+maze[x+1][y]+maze[x+1][y+1]+maze[x][y+1]);
top_c=(maze[x-1][y]+maze[x-1][y-1]+maze[x][y-1]+maze[x+1][y-1]+maze[x+1][y]);
bottom_c=(maze[x-1][y]+maze[x-1][y+1]+maze[x][y+1]+maze[x+1][y+1]+maze[x+1][y]);

if( (left_c==0 || right_c==0 || top_c==0 || bottom_c==0) && (is_odd(x)==0 || is_odd(y)==0) )
{
return 1;
}
else
{
return 0;
}
}
}



/* tests number to see if odd */
unsigned char is_odd(unsigned char to_test)
{
div_t result;
result=div(to_test,2);
return result.rem;
}



/* generates a random number in range */
unsigned char random_value(unsigned char range)
{
div_t result;
result=div(rand(),range);
return result.rem;
}



/* counts neighbouring blocks to side and above and below */
unsigned char adjacent_neighbours(unsigned char x, unsigned char y)
{
return maze[x-1][y]+maze[x][y-1]+maze[x+1][y]+maze[x][y+1];
}



/* counts diagonal neighbours */
unsigned char diagonal_neighbours(unsigned char x, unsigned char y)
{
return maze[x-1][y-1]+maze[x-1][y+1]+maze[x+1][y-1]+maze[x+1][y-1];
}
It simply scanns through the array and randomly places a block (or not) at locations where there is one adjacent neighbour and where either the x or y coordinates are odd and where there is space around it.

I expect there are better ways of acheiving this.

I found another similar thread here: http://www.raspberrypi.org/phpBB3/viewt ... on#p236440

Maybe this could be adapted to create road layouts. With the addition of a random 3d building generator you would have cities....

I dare someone to extend this minecraft code to 3D - ladders would be involved.

A 3D building generator would require a different aproach with perhaps stairs instead.

User avatar
davef21370
Posts: 897
Joined: Fri Sep 21, 2012 4:13 pm
Location: Earth But Not Grounded

Re: Minecraft Maze Generator

Sun Feb 17, 2013 5:33 pm

I'm already on with the 3D version :)
It's easy enough, I'm just going to create one maze with a roof above another and so on with ladders at opposite ends of each layer and a torch at every junction.

Gonna be next weekend though as for some perverse reason my boss expects me to work during the week ;)

Dave.
Apple say... Monkey do !!

jawabiscuit
Posts: 2
Joined: Wed Nov 21, 2012 3:13 am

Re: Minecraft Maze Generator

Tue Feb 19, 2013 12:46 am

Thanks @Dave Finch for this great example! This is my favorite of all the Minecraft scripts out there already. I’ve update this great tool with a little more Python fancy schmanciness. Made it object oriented and added some functionality with the idea of upgrading the algorithm to generate the maze, make it 3D, and add some funkiness.

I made a command line file for use in the terminal and moved the code to a mazeLib.py. Why? Now I can type the command

Code: Select all

minegenerator
in a terminal and build the maze like that or I can build and improve upon the Maze object that lives in mazeLib and debug it from an interactive terminal! I'm on my laptop and ssh'd into my pi so I needed a better debugging setup.

Create the two files below, chdir to /home/pi/mcpi/api/python/mcpi. You need to run code from here to work automatically. IMPORTANT, chmod the mazegenerator file you create to be executable by doing

Code: Select all

chmod 777 mazegenerator
The two files that need to go in /home/pi/mcpi/api/python/mcpi :

mazegenerator (note: do not use a file extension)

Code: Select all

#! /usr/bin/python
# Commandline maze generator for Minecraft Pi edition.
# @author: Jonas Avrin cghijinks@gmail.com

import sys
import traceback
import mazeLib

def main():
    '''Create a maze instance.'''
    m = mazeLib.Maze(sizex=10, sizey=10, max_wall_len=1, verbose=True)
    m.clear()
    m.initMaze()
    m.generate()

if __name__ == '__main__':
    try:
        result = main()
    except KeyboardInterrupt:
        print "Bye"
        sys.exit(1)
    if result:
        sys.exit(0)
    elif '--debug' in sys.argv:
        print traceback.sys.exc_info()
    else:
        sys.exit(1)
mineLib.py

Code: Select all

'''
Created on Feb 18, 2013
@originalAuthor: Dave Finch
@author: Jonas Avrin cghijinks@gmail.com
'''
import minecraft
import block
import random
from random import randint as rand


class Maze(object):
    ''''''
    def __init__(self, **kwargs):
        self.verbose = kwargs.setdefault('verbose', False)
        # Connect to minecraft :)
        self.mc = self.connect()
        self.maze = []
        self.spl = []

        # Define the X and Y size of the maze including the outer walls.
        self.sizex = kwargs.get('sizex', None)
        self.sizey = kwargs.get('sizey', None)
        self.dimms = ()
        if self.sizex and self.sizey:
            self.dimms = (self.sizex, self.sizey)
        else:
            self.sizex = kwargs.setdefault('sizex', 21)
            self.sizey = kwargs.setdefault('sizey', 21)
        if self.verbose:
            print '# MAZE DIMMS #\n' \
                + 'sizex: %d sizey: %d:' % (self.sizex, self.sizey)

        # Set maximum length of wall
        self.max_wall_len = kwargs.setdefault('max_wall_len', 1)
        # Find position of player and set base of maze 3 blocks lower.
        self.ppos = self.mc.player.getPos()
        self.ppos.y -= 3

    @property
    def dimms(self):
        return self.sizex, self.sizey

    @dimms.setter
    def dimms(self, val):
        if not isinstance(val, tuple):
            raise TypeError('Dimensions value type must be a tuple(x, y)')
        for v in val:
            if not self.isodd(v):
                self.sizex, self.sizey = [v + 1 for v in val]
            else:
                self.sizex, self.sizey = [v for v in val]

    def isodd(self, num):
            return num & 1 and True or False

    def create(self):
        # Create an empty maze.
        self.clear()
        self.initMaze()

    @staticmethod
    def connect():
        # Connect to Minecraft.
        try:
            mc = minecraft.Minecraft.create()
            return mc
        except:
            raise RuntimeError('Minecraft unavailable.')

    def clear(self):
        # Clear an area for the maze.
        for x in xrange(0, self.sizex - 1):
            for z in xrange(self.sizey - 1):
                self.mc.setBlock(self.ppos.x + x, self.ppos.y, self.ppos.z + z,
                                 block.STONE)
                for y in xrange(1, 6):
                    self.mc.setBlock(self.ppos.x + x, self.ppos.y + y,
                                     self.ppos.z + z, block.AIR)

    # Create a function to initialize the maze.
    def initMaze(self):
        # print player position
        if self.verbose:
            print 'player pos: %r' % self.ppos

        # Create a 2 dimensional array.
        self.maze = [[0] * self.sizey for x in xrange(self.sizex)]

        # print the maze
        if self.verbose:
            colsize = 0
            for m in self.maze:
                print ''.join(('%-*s' % (colsize + 3, i) for i in m))

        # Create four walls around the maze.
        # 1=wall, 0=walkway.
        for x in xrange(0, self.sizex):
            self.maze[x][0] = self.maze[x][self.sizey - 1] = 1
            self.makeWall(self.ppos.x + x, self.ppos.z + 0)
            self.makeWall(self.ppos.x + x, self.ppos.z + self.sizey - 1)
        for y in xrange(0, self.sizey):
            self.maze[0][y] = self.maze[self.sizex - 1][y] = 1
            self.makeWall(self.ppos.x, self.ppos.z + y)
            self.makeWall(self.ppos.x + self.sizex - 1, self.ppos.z + y)

        # Make every other cell a starting point.
        # 2=starting point.
        # Also create a list of these points to speed up the main loop.
        for y in xrange(2, self.sizey - 1, 2):
            for x in xrange(2, self.sizex - 2, 2):
                self.maze[x][y] = 2
                self.spl.append((x, y))

        # print the initialized maze
        if self.verbose:
            colsize = 0
            print 'maze initialized: \n'
            for m in self.maze:
                print ''.join(('%-*s' % (colsize + 3, i) for i in m))

            print '\n', 'rand spl: %r' % self.spl

        # Shuffle the list of points and we can choose a random point by
        # simply "popping" it off the list.
        random.shuffle(self.spl)
        if self.verbose:
            print 'rand spl: %r' % self.spl

    # Create a function for picking a random direction.
    def randDir(self):
        r = rand(0, 3)
        # Up.
        if r == 0:
            rv = (0, -1)
        # Down.
        if r == 1:
            rv = (0, 1)
        # Left.
        if r == 2:
            rv = (-1, 0)
        # Right.
        if r == 3:
            rv = (1, 0)
        return rv

    def generate(self):
        # Loop until we have no more starting points (2's in the empty maze)
        while filter(lambda x: 2 in x, self.maze):
            # Get the X and Y values of the first point in our randomized list.
            rx = self.spl[0][0]
            ry = self.spl[0][1]
            # Pop the first entry in the list, this deletes it,
            # the rest move down.
            self.spl.pop(0)
            # Check to see if our chosen point is still a valid starting point.
            ud = False
            if self.maze[rx][ry] == 2:
                ud = True
                # Pick a random wall length up to the maximum.
                rc = rand(0, self.max_wall_len)
                # Pick a random direction.
                rd = self.randDir()
                fc = rd
                loop = True
                while loop:
                    # Look in each direction, if the current wall being built
                    # is stuck inside itself start again.
                    if (self.maze[rx][ry - 2] == 3 and
                       self.maze[rx][ry + 2] == 3 and
                       self.maze[rx - 2][ry] == 3 and
                       self.maze[rx + 2][ry] == 3):
                        #
                        # Code to clear maze area required
                        #
                        self.initMaze(self.sizex, self.sizey)
                        break
                    # Look ahead to see if we're okay to go in this direction.
                    cx = rx + (rd[0] * 2)
                    cy = ry + (rd[1] * 2)
                    nc = self.maze[cx][cy]
                    if nc != 3:
                        for i in xrange(0, 2):
                            self.maze[rx][ry] = 3
                            self.makeWall(self.ppos.x + rx, self.ppos.z + ry)
                            rx += rd[0]
                            ry += rd[1]
                    # .....if not choose another direction.
                    else:
                        rd = self.randDir()
                    # If we hit an existing wall break out of the loop.
                    if nc == 1:
                        loop = False
                    # Update our wall length counter.
                    # When this hits zero pick another direction.
                    # This also makes sure the new direction
                    # isn't the same as the current one.
                    rc -= 1
                    if rc <= 0:
                        rc = rand(0, self.max_wall_len)
                        dd = rd
                        de = (fc[0] * -1, fc[1] * -1)
                        while dd == rd or rd == de:
                            rd = self.randDir()
            # The latest wall has been built so
            # change all 3's (new wall) to 1's (existing wall)
            if ud:
                for x in xrange(0, self.sizex):
                    for y in xrange(0, self.sizey):
                        if self.maze[x][y] == 3:
                            self.maze[x][y] = 1

    def makeWall(self, x, z):
        self.mc.setBlock(x, self.ppos.y, z, block.STONE)
        self.mc.setBlock(x, self.ppos.y + 1, z, block.STONE)
        self.mc.setBlock(x, self.ppos.y + 2, z, block.STONE)

I tried to make a couple improvements by adding in some parameters to control the width, height, max wall size, and turning verbose on and off.

Here's an example of what you can do:
In the /home/pi/mcpi/api/python/mcpi directory launch python by typing python and just look at my terminal below to get an idea.

Code: Select all

pi@raspberrypi ~/mcpi/api/python/mcpi $ python
Python 2.7.3 (default, Jan 13 2013, 11:20:46)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mazeLib
>>> m=mazeLib.Maze(sizex=10, sizey=10, max_wall_len=1)
>>> m.dimms
(11, 11)
>>> m.create()
>>> m.verbose = True
>>> m.create()
player pos: Vec3(9.91611,0.99797,36.0579)
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
maze initialized:

1  1  1  1  1  1  1  1  1  1  1
1  0  0  0  0  0  0  0  0  0  1
1  0  2  0  2  0  2  0  2  0  1
1  0  0  0  0  0  0  0  0  0  1
1  0  2  0  2  0  2  0  2  0  1
1  0  0  0  0  0  0  0  0  0  1
1  0  2  0  2  0  2  0  2  0  1
1  0  0  0  0  0  0  0  0  0  1
1  0  2  0  2  0  2  0  2  0  1
1  0  0  0  0  0  0  0  0  0  1
1  1  1  1  1  1  1  1  1  1  1

rand spl: [(2, 6), (8, 2), (6, 2), (2, 8), (6, 4), (8, 4), (8, 6), (4, 4), (2, 2), (6, 8), (4, 8), (6, 6), (8, 8), (4, 6), (2, 4), (4, 2), (2, 2), (4, 2), (6, 2), (8, 2), (2, 4), (4, 4), (6, 4), (8, 4), (2, 6), (4, 6), (6, 6), (8, 6), (2, 8), (4, 8), (6, 8), (8, 8)]
rand spl: [(8, 4), (8, 2), (4, 4), (4, 2), (8, 2), (6, 4), (4, 8), (2, 8), (2, 2), (4, 8), (4, 6), (2, 8), (4, 2), (6, 6), (2, 6), (8, 4), (8, 6), (4, 4), (8, 8), (6, 2), (6, 8), (2, 4), (6, 6), (8, 6), (2, 6), (6, 4), (6, 2), (2, 4), (2, 2), (6, 8), (4, 6), (8, 8)]
>>> m.generate()
Explanation:

Instance of Maze is created with some custom sizing. You can call it with no arguments and it still works with some built in defaults.

Code: Select all

>>> m=mazeLib.Maze(sizex=10, sizey=10, max_wall_len=1)
The Maze object has a computed attribute called dimms, short for dimensions

Code: Select all

>>> m.dimms
Change the dimms attribute by setting it with another tuple or query it

Code: Select all

>>> m.dimms
(11, 11)
m.dimms = (20, 20)
>>> m.dimms
(21, 21)
Q: Why is this spitting out 21 instead of 20? A: The computed attribute checks to see if the number given is even and spits out an odd number. Quick explanation is that it makes it cleaner to do some computations with other functions to actually generate the maze and may help later when extending the object, I'm not sure on that part yet.

This is a method that can be called that just makes it easier to create the maze by combining some of the functions that do the actual building. It initializes it but doesn't do the generating algorithm to actually fill in the maze.

Code: Select all

>>> m.create()
Turn verbose on/off interactively for debugging purposes.

Code: Select all

>>> m.verbose = True
The create method is being called with verbose on. Notice, the formatted printing to better visualize what's happening with the 2d array.

Code: Select all

>>> m.create()
player pos: Vec3(9.91611,0.99797,36.0579)
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0
maze initialized:

1  1  1  1  1  1  1  1  1  1  1
1  0  0  0  0  0  0  0  0  0  1
1  0  2  0  2  0  2  0  2  0  1
1  0  0  0  0  0  0  0  0  0  1
1  0  2  0  2  0  2  0  2  0  1
1  0  0  0  0  0  0  0  0  0  1
1  0  2  0  2  0  2  0  2  0  1
1  0  0  0  0  0  0  0  0  0  1
1  0  2  0  2  0  2  0  2  0  1
1  0  0  0  0  0  0  0  0  0  1
1  1  1  1  1  1  1  1  1  1  1

rand spl: [(2, 6), (8, 2), (6, 2), (2, 8), (6, 4), (8, 4), (8, 6), (4, 4), (2, 2), (6, 8), (4, 8), (6, 6), (8, 8), (4, 6), (2, 4), (4, 2), (2, 2), (4, 2), (6, 2), (8, 2), (2, 4), (4, 4), (6, 4), (8, 4), (2, 6), (4, 6), (6, 6), (8, 6), (2, 8), (4, 8), (6, 8), (8, 8)]
rand spl: [(8, 4), (8, 2), (4, 4), (4, 2), (8, 2), (6, 4), (4, 8), (2, 8), (2, 2), (4, 8), (4, 6), (2, 8), (4, 2), (6, 6), (2, 6), (8, 4), (8, 6), (4, 4), (8, 8), (6, 2), (6, 8), (2, 4), (6, 6), (8, 6), (2, 6), (6, 4), (6, 2), (2, 4), (2, 2), (6, 8), (4, 6), (8, 8)]
Turn verbose back off:

Code: Select all

>>> m.verbose = False
Generate the maze interior (run the algorithm to make the maze).

Code: Select all

>>> m.generate()
That's it! I hope that explains what I did and hopefully it looks a bit cleaner and gives you some alternatives to how you can run scripts in minecraft. I am a bit perplexed as to how thrown together some of the scripts are out there, have a look at PEP8 http://www.python.org/dev/peps/pep-0008/ people! It sounds nit-picky but one of the most important ideas Python was written with is the idea of legible code. That's not to say the original wasn't legible, now it's just more legible! :)

Have fun debugging and extending the maze! I know I will.
I was having a look at some other maze algorithms like random walk as alternative methods. A 3D maze would be outstanding as well!

Return to “Python”