我整天都在为迷宫生成算法编写一些代码。在这个片段中:
if nextCoords[2] == '<':
cells[x][y].l = False
x, y = nextCoords[0], nextCoords[1]
cells[x][y].r = False
if
语句的第一行cells[x][y].l = False
按预期执行,但出于某种原因,cells[x][y].r = False
无法保留更改。
这里是完整的代码(有一些print
来自无望的调试):
import random
class Cell():
def __init__(self, x, y):
self.x = x
self.y = y
self.visited = False
self.isStart = False
self.isEnd = False
self.isNormal = True
self.u = True
self.d = True
self.l = True
self.r = True
def __str__(self):
# For console applications
return "{0}{1}{2}{3}{4}{5}{6}".format(
'^' if not self.u else ' ',
'v' if not self.d else ' ',
'<' if not self.l else ' ',
'>' if not self.r else ' ',
'+' if self.isStart else '',
'@' if self.isEnd else '',
' ' if self.isNormal else ''
)
def __repr__(self):
return self.__str__()
def mazegen(w=3, h=3, printOut=False):
x = 0
y = 0
cells = [[Cell(x, y) for x in range(w)] for y in range(h)]
stack = []
cells[x][y].isStart = True
cells[x][y].isNormal = False
while True:
allVisited = True
for i in cells:
for j in i:
if not j.visited:
allVisited = False
if allVisited:
finalCell = cells[ stack[-1][0] ][ stack[-1][1] ]
finalCell.isNormal = False
finalCell.isEnd = True
break
cells[x][y].visited = True
choices = []
if x > 0:
choices.append((x-1, y, '<'))
if x < w-1:
choices.append((x+1, y, '>'))
if y > 0:
choices.append((x, y-1, '^'))
if y < h-1:
choices.append((x, y+1, 'v'))
betterChoices = []
for c in choices:
if not cells[ c[0] ][ c[1] ].visited:
betterChoices.append(c)
if betterChoices != []:
nextCoords = random.choice(betterChoices)
else:
popped = stack.pop()
x, y = popped[0], popped[1]
continue
stack.append((x, y))
print(nextCoords[2])
if nextCoords[2] == '^':
cells[x][y].u = False
print("This cell is now {}.".format(cells[x][y]))
x, y = nextCoords[0], nextCoords[1]
cells[x][y].d = False
print("The next cell is {}.".format(cells[x][y]))
if nextCoords[2] == 'v':
cells[x][y].d = False
print("Old: ({0}, {1})".format(x, y))
print(cells[x][y])
x, y = nextCoords[0], nextCoords[1]
print("New: ({0}, {1})".format(x, y))
print(cells[x][y])
cells[x][y].u = False
print(cells[x][y])
if nextCoords[2] == '<':
cells[x][y].l = False
x, y = nextCoords[0], nextCoords[1]
cells[x][y].r = False
if nextCoords[2] == '>':
cells[x][y].r = False
x, y = nextCoords[0], nextCoords[1]
cells[x][y].l = False
print("Moved {}\n".format(nextCoords[2]))
if printOut:
for i in cells:
for j in i:
print("| ", end='')
print(j, end=' | ')
print()
print("----------"*w)
return cells
答案 0 :(得分:0)
import pygame, sys, random
class Cell:
visited=isStart=isEnd=False
u=d=l=r=isNormal=True
def __init__(self,x,y): self.x,self.y = x,y
def mazegen(w,h):
x,y = 0,0
cells = [[Cell(x,y) for y in range(h)] for x in range(w)]
stack = []
cells[x][y].isStart = True
cells[x][y].isNormal = False
while True:
allVisited = True
for i in cells:
for j in i:
if not j.visited: allVisited = False
if allVisited:
finalCell = cells[ stack[-1][0] ][ stack[-1][1] ]
finalCell.isNormal = False
finalCell.isEnd = True
break
cells[x][y].visited = True
choices = []
if x>0: choices.append((x-1, y, '<'))
if x<w-1: choices.append((x+1, y, '>'))
if y>0: choices.append((x, y-1, '^'))
if y<h-1: choices.append((x, y+1, 'v'))
betterChoices = []
for c in choices:
if not cells[c[0]][c[1]].visited: betterChoices.append(c)
if betterChoices != []:
nextCoords = random.choice(betterChoices)
else:
popped = stack.pop()
x,y = popped[0],popped[1]
continue
stack.append((x,y))
if nextCoords[2] == '^':
cells[x][y].u = False
x,y = nextCoords[0], nextCoords[1]
cells[x][y].d = False
if nextCoords[2] == 'v':
cells[x][y].d = False
x,y = nextCoords[0], nextCoords[1]
cells[x][y].u = False
if nextCoords[2] == '<':
cells[x][y].l = False
x,y = nextCoords[0], nextCoords[1]
cells[x][y].r = False
if nextCoords[2] == '>':
cells[x][y].r = False
x,y = nextCoords[0], nextCoords[1]
cells[x][y].l = False
return cells
BLACK = (0,0,0)
WHITE = (255,255,255)
RED = (255,0,0)
GREEN = (0,255,0)
BLUE = (0,0,255)
screen = pygame.display.set_mode((400,400))
pygame.display.set_caption("Maze Generator!")
cells = mazegen(10,10)
while True:
key = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type==pygame.QUIT: pygame.quit(); sys.exit()
if event.type==pygame.KEYDOWN:
if key[pygame.K_LALT] and event.key==pygame.K_F4: pygame.quit(); sys.exit() # alt + f4
screen.fill(BLUE)
for i in cells:
for cell in i:
img = pygame.Surface((20,20))
img.fill(WHITE)
if cell.u:pygame.draw.line(img,BLACK,(0,0),(20,0))
if cell.d: pygame.draw.line(img,BLACK,(0,20),(20,20))
if cell.l: pygame.draw.line(img,BLACK,(0,0),(0,20))
if cell.r: pygame.draw.line(img,BLACK,(20,0),(20,20))
screen.blit(img,(cell.x*20, cell.y*20))
pygame.display.flip()
这里也是我非常紧凑的例子。 (我使用pygame只是为了将其保存为图像。哈哈)
import pygame, random
def maze(*gs):
gs = (gs[0]+3-gs[0]%4,gs[1]+3-gs[1]%4) # rounding grid size for cleaner presentation
adjacent = lambda x,y: [(a,b) for a,b in ((x-2,y),(x+2,y),(x,y-2),(x,y+2)) if (a,b) not in tiles and a+1 and b+1 and a<gs[0] and b<gs[1]]
pos = (gs[0]//2,gs[1]//2); tiles, points, direction = [pos], [], (0,0)
for l in range(((gs[0]-1)//2)*((gs[1]-1)//2)-1): # total loops in algorithm
adj = adjacent(*pos) # get available adjacents
for i in points[::-1]:
if adj: break # we have adjacents, we don't need to backtrack
adj = adjacent(*i) # check if corner has spare adjacents
if adj: points, pos = points[:points.index(i)], i # if so, remove corner, backtrack pos
rand = random.choice(adj); new_dir = rand[0]-pos[0], rand[1]-pos[1] # get random dir
if new_dir != direction and len(adj)>1: points += [pos] # corner and more adj remain
tiles, pos, direction = tiles+[(rand[0]-new_dir[0]//2,rand[1]-new_dir[1]//2),rand], rand, new_dir # add path, move in direction
pygame.init() # lets use pygame
surface = pygame.Surface(gs); surface.fill((0,0,0)) # create black image
for i in tiles: surface.set_at(i,(255,255,255)) # add white path
pygame.image.save(surface,"maze.png") # save as png
maze(100,100) # create 100x100 pixel maze