summaryrefslogblamecommitdiff
path: root/misc/maze.py
blob: ebd494187ce49eb563a7ce3059ee1e0aa1f8b241 (plain) (tree)














































































































































                                                                                                                                                                     
#!/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()