python3练习,做一个迷宫生成程序
直接上代码:
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()