import random, tkinter from time import sleep class Display: def __init__(self, precent, m, pos, mode='NORMAL'): if len(m) > len(m[0]): self.unit = 650 / len(m) else: self.unit = 650 / len(m[0]) self.win = tkinter.Tk() self.win.title('Maze maker') self.precent = tkinter.Label(self.win, text=precent) self.precent.pack() self.canvas = tkinter.Canvas(self.win, width=len(m[0]) * self.unit, height=len(m) * self.unit) self.canvas.pack() y = 0 y1 = 0 for row in m: x = 0 x1 = 0 for cel in row: if [y1, x1] == pos: color = 'magenta' elif mode == 'DEBUG': color = {'#': 'black', 0: 'red', 1: 'orange', 2: 'yellow', 3: 'green', 4: 'blue', 5: 'purple', ' ': 'white', 'S': 'green', 'E': 'red'}[cel] else: if cel == '#': color = 'black' elif cel in [0, 1, 2, 3, 4, 5, ' ']: color = 'white' elif cel == 'S': color = 'green' elif cel == 'E': color = 'red' self.canvas.create_rectangle(x, y, x + self.unit, y + self.unit, fill=color, width=0) x += self.unit x1 += 1 y += self.unit y1 += 1 self.win.update() def update(self, precent, m, pos, mode='NORMAL'): self.precent.configure(text=precent) self.canvas.delete('all') y = 0 y1 = 0 #display(m) for row in m: x = 0 x1 = 0 for cel in row: if [y1, x1] == pos and mode != 'END': color = 'magenta' elif mode == 'DEBUG': color = {'#': 'black', 0: 'red', 1: 'orange', 2: 'yellow', 3: 'green', 4: 'blue', 5: 'purple', ' ': 'white', 'S': 'green', 'E': 'red'}[cel] else: if cel == '#': color = 'black' elif cel in [0, 1, 2, 3, 4, 5, ' ']: color = 'white' elif cel == 'S': color = 'green' elif cel == 'E': color = 'red' self.canvas.create_rectangle(x, y, x + self.unit, y + self.unit, fill=color, width=0) x += self.unit x1 += 1 y += self.unit y1 += 1 self.win.update() def arraym(a, op, b): if op == '+': op = lambda x, y: x + y r = [] if len(a) > len(b): for i in range(0, len(b)): r.append(op(a[i], b[i])) else: for i in range(0, len(a)): r.append(op(a[i], b[i])) return r def getSpace(pos, m): if 0 > pos[0] or pos[0] >= len(m) or 0 > pos[1] or pos[1] >= len(m[0]): return '?' return m[pos[0]][pos[1]] def setSpace(pos, c, m): m[int(pos[0])][int(pos[1])] = c def getoptions(pos, m): dirs = [[-2, 0, 2], [0, 2, 3], [2, 0, 0], [0, -2, 1]] options = [] for d in dirs: #print(getSpace([pos[0] + d[0], pos[1] + d[1]], m)) if getSpace(arraym(d, '+', pos), m) == '#': options.append(d) return options def display(m): s = '' for row in m: for cel in row: s = s + str(cel) s = s + '\n' print(s) def finalize(m, start, end): s = '' ar = [] a = 0 for row in m: ar.append([]) b = 0 for cel in row: if cel == '#': s = s + '#' ar[a].append('#') elif [a, b] == start: s = s + 'S' ar[a].append('S') elif [a, b] == end: s = s + 'E' ar[a].append('E') else: s = s + ' ' ar[a].append(' ') b += 1 s = s + '\n' a += 1 return [s, ar] def makeMaze(height=11, length=11, mode='NORMAL', start=[1, 1], main='DEFULT'): if main == 'DEFULT': if __name__ == '__main__': main = True else: main = False progress = 0 outof = length * height length, height = length * 2 + 1, height * 2 + 1 m = [] e = True ends = [] for a in range(0, height): m.append([]) for b in range(0, length): m[a].append('#') dirs = [[-2, 0, 2], [0, 2, 3], [2, 0, 0], [0, -2, 1]] pos = [start[0], start[1]] running = True setSpace(pos, ' ', m) win = Display(str(int(progress / outof * 100)) + '%' + ' ' + str(progress) + '/' + str(outof), m, pos) while running: #input() #display(m) options = getoptions(pos, m) #print(pos, options) if len(options) > 0: progress += 1 e = True goto = random.choice(options) #print(str(int(progress / outof * 100)) + '%' + ' ' + str(progress) + '/' + str(outof)) #print(goto) setSpace(arraym(pos, lambda x, y: y / 2 + x, goto), ' ', m) pos = arraym(pos, '+', goto) setSpace(pos, goto[2], m) else: #print('backTrack...') if pos == start: running = False else: if e == True: ends.append(pos) e = False pos = arraym(pos, '+', dirs[getSpace(pos, m)]) if mode == 'FAST' or main == False: win.update(str(int(progress / outof * 100)) + '%' + ' ' + str(progress) + '/' + str(outof), [], pos, mode) else: if main: win.update(str(int(progress / outof * 100)) + '%' + ' ' + str(progress) + '/' + str(outof), m, pos, mode) m = finalize(m, start, random.choice(ends)) if main: win.update('COMPLETE', m[1], pos, 'END') win.win.mainloop() else: win.win.destroy() return m[0] def make3DMaze(thickness=5, height=5, length=5, start=[1, 1, 1], main='DEFULT'): if main == 'DEFULT': if __name__ == '__main__': main = True else: main = False progress = 0 outof = thickness * height * length import tkinter if main: win = tkinter.Tk() win.title('Progress') win.geometry('300x300') lbl = tkinter.Label(win, text='0%') lbl.pack() info = tkinter.Label(win, text='xxxx') info.pack() length, height, thickness = length * 2 + 1, height * 2 + 1, thickness * 2 + 1 m = [] e = True ends = [] for a in range(0, thickness): m.append([]) for b in range(0, height): m[a].append([]) for c in range(0, length): m[a][b].append('#') #D ^ # 0 1 # T-| #<4-#-2> #- |T+ #H 3 5 #+ V U ###-L+### #[T, H, L, ID] #0:-2, 0, 0, 5 #1:0, -2, 0, 3 #2:0, 0, 2, 4 #3:0, 2, 0, 1 #4:0, 0, -2, 2 #5:2, 0, 0, 0 dirs = [[-2, 0, 0, 5], [0, -2, 0, 3], [0, 0, 2, 4], [0, 2, 0, 1], [0, 0, -2, 2], [2, 0, 0, 0]] pos = [start[0], start[1], start[2]] running = True setSpace3(pos, ' ', m) while running: #input() #display3(m) options = getoptions3(pos, m) #print(pos, options) if len(options) > 0: progress += 1 if main: lbl.configure(text=str(int(progress / outof * 100)) + '%' + ' ' + str(progress) + '/' + str(outof)) win.update() e = True goto = random.choice(options) if main: info.configure(text=['U', 'v', '<', '^', '>', 'D'][goto[3]]) #print(goto) setSpace3(arraym(pos, lambda x, y: y / 2 + x, goto), ' ', m) pos = arraym(pos, '+', goto) setSpace3(pos, goto[3], m) else: #display3(m) #print('backTrack...') if main: info.configure(text='Backtrack') if pos == start: running = False else: if e == True: ends.append(pos) e = False current = getSpace3(pos, m) pos = arraym(pos, '+', dirs[getSpace3(pos, m)]) m = finalize3(m, start, random.choice(ends)) if main: win.destroy() return m def getSpace3(pos, m): if 0 > pos[0] or pos[0] >= len(m) or 0 > pos[1] or pos[1] >= len(m[0]) or 0 > pos[2] or pos[2] >= len(m[0][0]): return '?' return m[pos[0]][pos[1]][pos[2]] def setSpace3(pos, c, m): m[int(pos[0])][int(pos[1])][int(pos[2])] = c def getoptions3(pos, m): dirs = [[-2, 0, 0, 5], [0, -2, 0, 3], [0, 0, 2, 4], [0, 2, 0, 1], [0, 0, -2, 2], [2, 0, 0, 0]] options = [] for d in dirs: #print(getSpace3(arraym(pos, '+', d), m)) if getSpace3(arraym(pos, '+', d), m) == '#': options.append(d) return options def display3(m): s = '' for layer in m: for row in layer: for cel in row: s = s + str(cel) s = s + '\n' s = s + '\n' print(s) def finalize3(m, start, end): s = '' a = 0 for layer in m: b = 0 if a % 2 == 1: for row in layer: c = 0 for cel in row: if cel == '#': s = s + '#' elif [a, b, c] == start: s = s + 'S' elif [a, b, c] == end: s = s + 'E' elif getSpace3([a - 1, b, c], m) == ' ' and getSpace3([a + 1, b, c], m) == ' ': s = s + '0' elif getSpace3([a + 1, b, c], m) == ' ': s = s + 'U' elif getSpace3([a - 1, b, c], m) == ' ': s = s + 'D' else: s = s + ' ' c += 1 s = s + '\n' b += 1 s = s + '\n\n' a += 1 return s if __name__ == '__main__': print('Use Ctrl+C to skip') try: print('2D Maze:') makeMaze(int(input('Height? ')), int(input('Width? ')), input('Mode (DEBUG, NORMAL, FAST)? ')) except KeyboardInterrupt: print('Skiped') try: print('\n3D Maze:') print(make3DMaze(int(input('Thickness? ')), int(input('Height? ')), int(input('Width? ')))) except KeyboardInterrupt: print('Skiped')