diff options
-rwxr-xr-x | misc/maze.py | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/misc/maze.py b/misc/maze.py new file mode 100755 index 0000000..ebd4941 --- /dev/null +++ b/misc/maze.py @@ -0,0 +1,143 @@ +#!/usr/bin/python2 + +import numpy +from numpy.random import randint as rand +import sys + +def tile(): + tiles=[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, + 1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,10] + return str(tiles[rand(len(tiles))]) + +def generate_maze(width=81, height=51, complexity=.75, density=.75): + """Generate a maze using a maze generation algorithm.""" + # Only odd shapes + shape = ((height // 2) * 2 + 1, (width // 2) * 2 + 1) + # Adjust complexity and density relative to maze size + complexity = int(complexity * (5 * (shape[0] + shape[1]))) # Number of components + density = int(density * ((shape[0] // 2) * (shape[1] // 2))) # Size of components + # Build actual maze + Z = numpy.zeros(shape, dtype=int) + # Fill borders + Z[0, :] = Z[-1, :] = 1 + Z[:, 0] = Z[:, -1] = 1 + # Make aisles + for i in range(density): + x, y = rand(0, shape[1] // 2) * 2, rand(0, shape[0] // 2) * 2 # Pick a random position + Z[y, x] = 1 + for j in range(complexity): + neighbours = [] + if x > 1: neighbours.append((y, x - 2)) + if x < shape[1] - 2: neighbours.append((y, x + 2)) + if y > 1: neighbours.append((y - 2, x)) + if y < shape[0] - 2: neighbours.append((y + 2, x)) + if len(neighbours): + y_, x_ = neighbours[rand(0, len(neighbours) - 1)] + if Z[y_, x_] == 0: + Z[y_, x_] = 1 + Z[y_ + (y - y_) // 2, x_ + (x - x_) // 2] = 1 + x, y = x_, y_ + return Z + +# Receive arguments from commandline +try: + MaxMazes = int(sys.argv[1]) + x = int(sys.argv[2]) + y = int(sys.argv[3]) +except IndexError: + print("Usage: ./maze.py <number of mazes> <width> <height>") + print("") + print("Creates random mazes. Must strip final comma and automap. Reorder.") + exit(0) + + +# Base class +class dlist(list): + def __setitem__(self, index, value): + size = len(self) + if index >= size: + self.extend(0 for _ in range(size, index + 1)) + list.__setitem__(self, index, value) + +def MakeMaze(maze): + TRUEMAZE=[] + xc=yc=1 # Cursors + + # Setup TRUEMAZE + i=0 + while i < (y+1): + # Three instances per Y + TRUEMAZE.append(dlist()) + TRUEMAZE.append(dlist()) + TRUEMAZE.append(dlist()) + i+=1 + + # Build TRUEMAZE + for row in maze: + for r in row: + r=str(r) + #print "(%d, %d) = %s" % (xc, yc, r) + TRUEMAZE[max(0, yc-1)][max(0, xc-1)]=int(r.replace('1', '5').replace('0', tile())) + TRUEMAZE[max(0, yc-1)][max(0, xc)]=int(r.replace('1', '5').replace('0', tile())) + TRUEMAZE[max(0, yc-1)][max(0, xc+1)]=int(r.replace('1', '5').replace('0', tile())) + + TRUEMAZE[max(0, yc)][max(0, xc-1)]=int(r.replace('1', '5').replace('0', tile())) + TRUEMAZE[max(0, yc)][max(0, xc)]=int(r.replace('1', '5').replace('0', tile())) + TRUEMAZE[max(0, yc)][max(0, xc+1)]=int(r.replace('1', '5').replace('0', tile())) + + TRUEMAZE[max(0, yc+1)][max(0, xc-1)]=int(r.replace('1', '5').replace('0', tile())) + TRUEMAZE[max(0, yc+1)][max(0, xc)]=int(r.replace('1', '5').replace('0', tile())) + TRUEMAZE[max(0, yc+1)][max(0, xc+1)]=int(r.replace('1', '5').replace('0', tile())) + + xc+=3 + + xc=1 + yc+=3 + return TRUEMAZE + +# Begin +print "Begin!" + +MazeID=0 +while MazeID < MaxMazes: + MazeID+=1 + print "Building Maze %02d/%02d!" % (MazeID, MaxMazes) + maze=generate_maze(x, y) + + print repr(maze) + + TRUEMAZE=MakeMaze(maze) + width=len(TRUEMAZE[1]) + name="mz%03d_%02d%02d.tmx" % (MazeID, x, y) + + f=open(name, "w"); + print "open // %s" % name + + # Write the TMX file + f.write("""<?xml version="1.0" encoding="UTF-8"?> + <map version="1.0" tiledversion="1.0.3" orientation="orthogonal" renderorder="right-down" width="%d" height="%d" tilewidth="32" tileheight="32" nextobjectid="1"> + <properties> + <property name="AutomappingRadius" value="1"/> + <property name="DeleteTiles" value="true"/> + </properties> + <tileset firstgid="1" name="set_cave" tilewidth="32" tileheight="32" tilecount="64" columns="8"> + <image source="../Rules/tilesets/set_cave.png" width="256" height="256"/> + </tileset> + <layer name="set" width="%d" height="%d"> + <data encoding="csv"> + """ % (width, (y+1)*3, width, (y+1)*3)) + + for line in TRUEMAZE: + if line != []: + f.write(str(line).replace('[','').replace(']','').replace(' ','')+",\n") + + f.write(""" </data> + </layer> + </map>""") + + + # And, we're done + f.close() + + |