|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- import random as r
- import sys, os
- from PIL import Image
-
- def createDungeon(x=None, y=None, seed=None):
- """ Initializes an x by y grid.
- x is width, y is height
- seed is the chance that a given cell will be "live" and should be an integer between 1-99.
- If True is equivalent to "wall", then higher seeds make more walls.
- """
- x = 10 if x == None else int(x)
- y = 10 if y == None else int(y)
- seed = 45 if seed == None else int(seed)
- new_map = []
- for j in range(y):
- new_row = []
- for i in range(x):
- new_row.append(True if r.randint(1,99) <= seed else False)
- new_map.append(new_row)
- return new_map
-
- def refineDungeon(d_map, d_lmt=None, a_lmt=None):
- """ Refines the grid.
- """
- d_lmt = 4 if d_lmt == None else int(d_lmt)
- a_lmt = 4 if a_lmt == None else int(a_lmt)
- new_map = []
- for j in range(len(d_map)):
- new_line = []
- for i in range(len(d_map[j])):
- x, y = i, j
- n_count = countAliveNeighbors(d_map, x, y)
- if d_map[y][x]:
- # It's a wall.
- if n_count < d_lmt:
- # It has too few wall neighbors, so kill it.
- new_line.append(False)
- else:
- # It has enough wall neighbors, so keep it.
- new_line.append(True)
- else:
- # It's a path.
- if n_count > a_lmt:
- # It has too many wall neighbors, so it becomes a wall.
- new_line.append(True)
- else:
- # It's not too crowded, so it stays a path.
- new_line.append(False)
- new_map.append(new_line)
- return new_map
-
- def countAliveNeighbors(d_map, x, y):
- count = 0
- for j in range(-1,2):
- for i in range(-1,2):
- n_x, n_y = x+i, y+j
- if i == 0 and j == 0:
- continue
- if n_x < 0 or n_x >= len(d_map[j]) or n_y == 0 or n_y >= len(d_map):
- # The target cell is at the edge of the map and this neighbor is off the edge.
- # So we make this neighbor count as a wall.
- count += 1
- #pass
- elif d_map[n_y][n_x]:
- # This neighbor is on the map and is a wall.
- count += 1
- return count
-
- def printDungeon(d_map, wall=None, path=None):
- wall = "II" if wall == None else wall
- path = " " if path == None else path
- for line in d_map:
- print("".join([wall if x else path for x in line]))
- print()
-
- def createImage(d_map, color=None, chunky=None, fn=None):
- color = False if color == None else bool(color)
- chunky = False if chunky == None else bool(chunky)
- fn = filename() if fn == None else fn
- x, y = len(d_map[0]), len(d_map)
- if chunky:
- true_x, true_y = x*2, y*2
- else:
- true_x, true_y = x, y
- img = Image.new("RGB",(true_x,true_y),(0,0,0))
- lst = []
- # Walls are black by default
- c_wall = [r.randint(0,255), r.randint(0,255), r.randint(0,255)] if color else [0,0,0]
- # Paths are white by default
- c_space = [255-x for x in c_wall]
- if chunky:
- for line in d_map:
- for _ in range(2):
- for val in line:
- for _ in range(2):
- lst.append(tuple(c_wall) if val else tuple(c_space))
- else:
- for line in d_map:
- for val in line:
- lst.append(tuple(c_wall) if val else tuple(c_space))
- img.putdata(lst)
- if not os.path.exists("maps"):
- os.makedirs("maps")
- img.save('maps/{}.png'.format(fn))
- print("Saved maps/{}.png".format(fn))
-
- def filename():
- hexes = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"]
- fn = []
- for _ in range(16):
- fn.append(r.choice(hexes))
- return "".join(fn)
-
-
- def main(x=None, y=None, seed=None, d_lmt=None, a_lmt=None, reps=None, out=None, color=None, chunky=None):
- # Initialize
- x = 20 if x == None else int(x)
- y = 20 if y == None else int(y)
- seed = 45 if seed == None else int(seed)
- d_lmt = 4 if d_lmt == None else int(d_lmt)
- a_lmt = 4 if a_lmt == None else int(a_lmt)
- reps = 2 if reps == None else int(reps)
- out = False if out == None else bool(out)
- color = False if color == None else bool(color)
- chunky = False if chunky == None else bool(chunky)
- my_map = createDungeon(x,y,seed)
- fn = filename()
- for _ in range(reps):
- my_map = refineDungeon(my_map, d_lmt, a_lmt)
- if out:
- createImage(my_map, color, chunky)
- else:
- printDungeon(my_map)
-
- def parseArgs(args):
- flags = {
- "--height" : 20,
- "--width" : 20,
- "--seed" : 45,
- "--death" : 4,
- "--birth" : 4,
- "--reps" : 2,
- "--out" : False,
- "--color" : False,
- "--chunky" : False,
- }
- for flag, default in flags.items():
- if flag in args:
- if flag == "--out":
- flags["--out"] = True
- elif flag == "--color":
- flags["--color"] = True
- elif flag == "--chunky":
- flags["--chunky"] = True
- else:
- flags[flag] = args[args.index(flag) + 1]
- return flags
-
- if __name__ == "__main__":
- flags = parseArgs(sys.argv)
-
- main(flags["--width"],
- flags["--height"],
- flags["--seed"],
- flags["--death"],
- flags["--birth"],
- flags["--reps"],
- flags["--out"],
- flags["--color"],
- flags["--chunky"])
|