-
Notifications
You must be signed in to change notification settings - Fork 0
/
maze_gen.py
executable file
·120 lines (104 loc) · 3.85 KB
/
maze_gen.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#! /usr/bin/env python3
from enum import Flag, auto
import random
class Direction(Flag):
N = auto()
E = auto()
S = auto()
W = auto()
ALL_WALLS = Direction.N | Direction.E | Direction.S | Direction.W
NO_WALLS = Direction.N & Direction.S
def opposite_direction(d):
if d is Direction.N:
return Direction.S
if d is Direction.S:
return Direction.N
if d is Direction.E:
return Direction.W
return Direction.E
def random_suit(is_red):
if is_red:
return '█'
return random.choice((' ', ' ', ' ', '"', '.', '^'))
def dfs_maze(grid, x, y):
grid[y][x] = (True, grid[y][x][1], grid[y][x][2])
neighbours = [
(x, y-1, Direction.N),
(x+1, y, Direction.E),
(x, y+1, Direction.S),
(x-1, y, Direction.W)]
random.shuffle(neighbours)
for i, j, d in neighbours:
if 0 <= i < maze_x and 0 <= j < maze_y and not grid[j][i][0]:
grid[y][x] = (True, grid[y][x][1] & ~d, grid[y][x][2])
grid[j][i] = (True, grid[j][i][1] & ~opposite_direction(d),
grid[j][i][2])
dfs_maze(grid, i, j)
def maze_box_char(top_left, top_right, bottom_left):
if top_left & Direction.E:
if top_left & Direction.S:
if bottom_left & Direction.E:
return '┼' if top_right & Direction.S else '┤'
return '┴' if top_right & Direction.S else '┘'
if bottom_left & Direction.E:
return '├' if top_right & Direction.S else '│'
return '└' if top_right & Direction.S else '╵'
else:
if bottom_left & Direction.E:
if top_left & Direction.S:
return '┬' if top_right & Direction.S else '┐'
return '┌' if top_right & Direction.S else '╷'
if top_left & Direction.S:
return '─' if top_right & Direction.S else '╴'
return '╶' if top_right & Direction.S else ' '
def bold_box_char(x, y, char):
return char
def border(x, y, top_left, top_right=NO_WALLS, bottom_left=NO_WALLS):
return bold_box_char(x, y, maze_box_char(top_left, top_right, bottom_left))
# Read in the maze map
maze_map = open('maze_map.txt', 'r').readlines()
maze_x = len(maze_map[0])
maze_y = len(maze_map)
# Initialise blank maze (entirely walls)
maze = []
for i in range(maze_y):
row = []
for j in range(maze_x):
row.append((False, ALL_WALLS, random_suit(maze_map[i][j]=='#')))
maze.append(row)
# Add exit point
maze[maze_y-1][maze_x-1] = (False, ALL_WALLS & ~Direction.E, ' ')
# Generate the maze
dfs_maze(maze, 0, 0)
# Build the first row
output = []
row = []
row.append(border(0, 0, NO_WALLS, Direction.S, NO_WALLS))
for x in range(maze_x):
row.append(border(x, 0, Direction.S, Direction.S, NO_WALLS))
row.append(border(x, 0, Direction.S,
NO_WALLS if x+1 == maze_x else Direction.S, maze[0][x][1]))
output.append(row)
# Print the rest of the maze. Sorry this is utterly unreadable but I'm on a
# tight deadline here.
for y in range(maze_y):
row = []
start_wall = NO_WALLS if y == 0 else Direction.E
row.append(border(0, y, start_wall, NO_WALLS, start_wall))
for x in range(maze_x):
row.append(maze[y][x][2])
right_wall = maze[y][x][1] & Direction.E
row.append(border(x, y, right_wall, NO_WALLS, right_wall))
output.append(row)
row = []
row.append(border(maze_x-1, y, start_wall, maze[y][0][1],
NO_WALLS if y+1 == maze_y else Direction.E))
for x in range(maze_x):
bottom_wall = maze[y][x][1] & Direction.S
row.append(border(x, y, bottom_wall, bottom_wall))
row.append(border(x, y, maze[y][x][1],
maze[y][x+1][1] if x+1 < maze_x else NO_WALLS,
maze[y+1][x][1] if y+1 < maze_y else Direction.N))
output.append(row)
output = '\n'.join(''.join(row) for row in output)
print(output)