#!/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 block20(txt=True): if txt: return "5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,"; else: return [5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5]; 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]) ry = int(y) except IndexError: print("Usage: ./maze.py ") 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 def BuildLayer(LayerName, w, h, LayerData, invisible=False): if invisible: inv=' visible="0"' else: inv="" return(""" %s """ % (LayerName, w, h, inv, LayerData)) # Begin print "Begin!" MazeID=0 while MazeID < MaxMazes: MazeID+=1 y=ry+0 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) # Generate Margins MZLINE=str(TRUEMAZE[0]).replace('[','').replace(']','').replace(' ','').replace("10", "5").replace("1", "5").replace("2", "5")+"," MARGIN="" i=0 while i < 20: i+=1 MARGIN+=block20()+MZLINE+block20()+"\n" # Create the maze string MAZEDATA="" MAZEDATA+=MARGIN # Fill maze data for line in TRUEMAZE: if line != []: MAZEDATA+=block20() MAZEDATA+=(str(line).replace('[','').replace(']','').replace(' ','')) MAZEDATA+=","+block20()+"\n" # Clean MAZEDATA properly MAZEDATA+=MARGIN MAZEDATA=MAZEDATA[:-2]+"\n" #MAZEMPTY=MAZEDATA.replace("10", "1").replace("2", "1").replace("5", "0") MAZEMPTY=MAZEDATA.replace("10", "0").replace("1", "0").replace("2", "0").replace("5", "0")[:-1] # Margin fix width+=40 height=((y+1)*3)+40 y+=40 # Write the TMX file f.write(""" """ % (width, height)) # Build set layer f.write(BuildLayer("set", width, height, MAZEDATA)) # Build the other tile layers f.write(BuildLayer("Ground", width, height, MAZEMPTY)) f.write(BuildLayer("Fringe", width, height, MAZEMPTY)) f.write(BuildLayer("Over", width, height, MAZEMPTY)) # Build the other invisible layers f.write(BuildLayer("Collision", width, height, MAZEMPTY, True)) f.write(BuildLayer("Heights", width, height, MAZEMPTY, True)) # Close the mapfile f.write(""" """) # And, we're done f.close()