python3 exercise, do a maze generator

Directly on the code:

  1 #!/usr/bin/python3
  2 #coding=utf-8
  3 import random
  4 import tkinter as tk
  5 
  6 class Cell():
  7     TOP = (0)
  8     RIGHT = (1)
  9     BOTTOM = (2)
 10     LEFT = (3)
 11     def __init__(self, x, y):
 12         self.index = 0
 13         self.x = x
 14         self.y = y
 15         self.walls = [True, True, True, True]
 16         self.visited = False
 17     def __str__(self):
 18         return 'x:{}-y:{}, walls:{}'.format(self.x, self.y, self.walls)
 19     def Walls(self):
 20         return self.walls
 21     def delTop(self):
 22         self.walls[0] = False 
 23     def delRight(self):
 24         self.walls[1] = False
 25     def delBottom(self):
 26         self.walls[2] = False
 27     def delLeft(self):
 28         self.walls[3] = False
 29     def setWall(self, isWall, index):
 30         if index not in [0, 1, 2, 3]:
 31             return
 32         self.walls[index] = isWall
 33     def XY(self):
 34         return [self.x, self.y]
 35     def X(self):
 36         return self.x
 37     def Y(self):
 38         return self.y
 39     def isVisited(self):
 40         return self.visited
 41     def setVisited(self):
 42         self.visited = True
 43 
 44 class Maze():
 45     SIZE = (18)
 46     START = (0, 0)
 47     def __init__(self):
 48         self.size = self.SIZE
 49         self.bfsBuffer = []
 50         self.cells = \
 51                 [[Cell(y, x) for x in range(self.SIZE)] \
 52                 for y in range(self.SIZE)]
 53 
 54         self.current = self.cells[self.START[0]][self.START[1]]
 55 
 56 
 57     def __str__(self):
 58         info = '' 
 59         for rows in self.cells:
 60             for cell in rows:
 61                 info += str(cell)
 62         return info 
 63     def trblWalls(self, x, y):
 64         return self.cells[x][y].Walls()
 65     def visited(self, x, y):
 66         return self.cells[x][y].isVisited()
 67     def CurrentCell(self):
 68         return self.current
 69     def setCurrent(self, cell):
 70         self.current = cell
 71     def topCell(self):
 72         if 0 == self.current.Y():
 73             return None
 74         return self.cells[self.current.X()][self.current.Y() - 1]
 75     def rightCell(self):
 76         if self.current.X() == (self.SIZE - 1):
 77             return None
 78         return self.cells[self.current.X() + 1][self.current.Y()]
 79     def bottomCell(self):
 80         if self.current.Y() == (self.SIZE - 1):
 81             return None
 82         return self.cells[self.current.X()][self.current.Y() + 1]
 83     def leftCell(self):
 84         if 0 == self.current.X():
 85             return None
 86         return self.cells[self.current.X() - 1][self.current.Y()]
 87     def delWall(self, current, neighbor):
 88         x = current.X()
 89         y = current.Y()
 90         x2 = neighbor.X()
 91         y2 = neighbor.Y()
 92         #print("({}x{}) and ({}x{})".format(x, y, x2, y2))
 93 
 94         if (1 == (x - x2)):
 95             current.delLeft()
 96             neighbor.delRight()
 97         elif (-1 == (x - x2)):
 98             current.delRight()
 99             neighbor.delLeft()
100         if (1 == (y - y2)):
101             current.delTop()
102             neighbor.delBottom()
103         elif (-1 == (y - y2)):
104             current.delBottom()
105             neighbor.delTop()
106 
107     def checkNeighbor(self):
108         neighbor = []
109         top = self.topCell()
110         right = self.rightCell()
111         bottom = self.bottomCell()
112         left = self.leftCell()
113         if (None != top and not top.isVisited()):
114             neighbor.append(self.topCell())
115         if (None != right and not right.isVisited()):
116             neighbor.append(self.rightCell())
117         if (None != bottom and not bottom.isVisited()):
118             neighbor.append(self.bottomCell())
119         if (None != left and not left.isVisited()):
120             neighbor.append(self.leftCell())
121         count = len(neighbor)
122         if 0 == count:
123             
124             if (len(self.bfsBuffer) == 0):
125                 return
126             self.current = self.bfsBuffer.pop()
127             self.checkNeighbor()
128             
129             return
130             
131         old = self.current
132                
133         self.current = neighbor[random.randint(0, count - 1)]
134 
135         self.delWall(old, self.current)
136         #print('neighbor count:{} ->{}'.format(count, str(self.current)))
137         self.setUp()
138     
139     def setUp(self):
140         self.current.setVisited()
141         self.bfsBuffer.append(self.current)
142         self.checkNeighbor()
143         
144 class MazeUI():
145     winWidth = (600)
146     winHeight = (600)
147     def __init__(self):
148         self.maze = Maze()
149         self.ui = tk.Tk()
150         self.centeredDisplay()
151 
152         self.createMaze()
153 
154         self.ui.mainloop()
155     def centeredDisplay(self):
156         self.ui.title('Maze by jianc')
157         self.ui.geometry('{}x{}+{}+{}'.format( \
158                 self.winWidth, self.winHeight, \
159                 int((self.ui.winfo_screenwidth() - self.winWidth)/2), \
160                 int((self.ui.winfo_screenheight() - self.winHeight)/2)))
161         self.ui.resizable(False, False)
162     def createMaze(self):
163         self.cs = tk.Canvas(self.ui, bg = '#5f3c23')
164 
165         self.cs.pack(side = tk.TOP, fill = 'both', expand=1, \
166                 padx=0, ipadx=0, pady=0, ipady=0)
167 
168         self.maze.setUp()
169 
170         #print(self.maze)
171         self.drawCells()
172         
173     def drawCells(self):
174         w = float(self.winWidth / self.maze.SIZE)
175         h = float(self.winHeight / self.maze.SIZE)
176         current = self.maze.CurrentCell()
177         y = current.X()
178         x = current.Y()
179         self.cs.create_rectangle(y * w + 4, x * h + 4, (y + 1) * w - 4, (x + 1) * h - 4, \
180                 fill='#ff0000', width = 0)
181 
182 
183        
184         for rows in range(self.maze.SIZE):
185             for cols in range(self.maze.SIZE):
186                 top, right, bottom, left = self.maze.trblWalls(cols, rows)
187                 #print("top:{} right:{} bottom:{} left:{}".format(top, right, bottom, left))
188                 bVisited = self.maze.visited(rows, cols)
189 
190                 """if bVisited:
191                     self.cs.create_rectangle(rows * w + 10, cols * h + 10, \
192                             (rows + 1) * w - 10, (cols+ 1) * h - 10, fill='#00ff00', width = 0) 
193                 """
194                 if top:
195                     self.cs.create_line(cols * w, rows * h, \
196                             (cols + 1) * w, rows * h, width=5)
197                 if right:
198                     self.cs.create_line((cols + 1) * w, rows * h, \
199                             (cols + 1) * w, (rows + 1) * h, width=5)
200                 if bottom:
201                     self.cs.create_line((cols + 1) * w, (rows + 1) * h, \
202                             cols * w, (rows + 1) * h, width=5)
203                 if left:
204                     self.cs.create_line(cols * w, (rows + 1) * h, \
205                             cols * w, rows * h, width=5)
206         
207         current = self.maze.CurrentCell()
208         y = current.X()
209         x = current.Y()
210         self.cs.create_rectangle(y * w + 5, x * h + 5, (y + 1) * w - 5, (x + 1) * h - 5, \
211                 fill='#ff0000', width = 0)
212 
213 
214 
215 maze = MazeUI()

 

Guess you like

Origin www.cnblogs.com/jianc/p/11756131.html