我在一年前学习了迷宫生成算法,非常惊讶。在自己实现的时候,由于python递归的很慢,我当时用的是循环。迷宫生成的和走迷宫的算法晚上有很多,但当我真的想在游戏了生成一个迷宫时我发现了问题:墙太厚了,路太窄。
这是原来的算法(包含走迷宫)
import pygame
import sys
import json
import random
import collections
def draw_maze(maze):
for y in range(len(maze)):
for x in range(len(maze[y])):
if maze[y][x]==1:
color='blue'
elif maze[y][x]==2:
color='yellow'
elif maze[y][x]==0:
color='white'
sur = pygame.Surface((x_size, y_size))
sur.fill(pygame.color.Color(color))
sur_rect = sur.get_rect(center=(x * x_size + x_size / 2, y * y_size + y_size / 2))
screen.blit(sur, sur_rect)
def in_area(x,y):
if x>=0 and x<difficulty and y>=0 and y<difficulty+30:
return True
else:
return False
def go_mase():
# print(go_position)
no_way=True
curpos=go_position.pop()
old_go_pos.insert(0,curpos)
go_visited.append(curpos)
drawing_list.insert(0,curpos)
for pos in drawing_list:
all_maze[pos[0]][pos[1]]=2
for i in range(4):
newx = curpos[0] + direction[i][0]
newy = curpos[1] + direction[i][1]
if all_maze[newx][newy]!=1 and (newx,newy) not in go_visited:
# all_maze[curpos[0]][curpos[1]] = 2
go_position.append((newx,newy))
no_way=False
if no_way:
has_change=[]
all_break=False
# print(old_go_pos)
while True:
pos=old_go_pos[0]
for i in range(4):
newx = pos[0] + direction[i][0]
newy = pos[1] + direction[i][1]
if all_maze[newx][newy] != 1 and ((newx, newy) not in go_visited) and ((newx, newy) not in has_change):
# print((newx, newy))
all_break=True
if all_break:
break
all_maze[pos[0]][pos[1]] = 0
has_change.append(pos)
old_go_pos.remove(pos)
print(old_go_pos)
print(pos)
print(drawing_list)
drawing_list.remove(pos)
pygame.init()
difficulty=91
with open('maze_record.json','w') as obj:
json.dump({'maze':[[1]*(difficulty+30)]*difficulty},obj)
x_size,y_size=10,10
position=[(1,1)]
screen = pygame.display.set_mode(((difficulty+30)*x_size, y_size*difficulty))
screen.fill((225,225,225))
with open('maze_record.json') as obj:
all_maze=json.load(obj)['maze']
for x in range(1,difficulty,2):
for y in range(1,difficulty+30,2):
all_maze[x][y]=0
old_go_pos=[]
all_maze[1][0]=0
all_maze[-2][-1]=0
direction=[[-1,0],[0,1],[1,0],[0,-1]]
visited=[]
drawing_list=[]
go_visited=[]
go_position=collections.deque()
go_position.append((1,0))
FRs=pygame.time.Clock()
stop=False
space=False
while True:
screen.fill((225,225,225))
# 监听事件
for event in pygame.event.get():
# 判断事件类型
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# 判断是否按下某一个键
if event.type == pygame.KEYDOWN:
# 判断是否按下ESC键
if event.key == pygame.K_ESCAPE:
sys.exit()
if event.key == pygame.K_s:
with open('maze_record.json', 'w') as obj:
json.dump({'maze': [[1] * (difficulty + 30)] * difficulty}, obj)
if event.key==pygame.K_SPACE:
space=True
if position!=[]:
curpos=position.pop(random.randint(0,len(position)-1))
for i in range(4):
newx = curpos[0] + direction[i][0] * 2
newy = curpos[1] + direction[i][1] * 2
if in_area(newx,newy) and not ((newx,newy) in visited):
all_maze[curpos[0] + direction[i][0]][curpos[1] + direction[i][1]]=0
visited.append((newx,newy))
position.append((newx,newy))
if position==[] and space:
# while not stop:
# if (difficulty-1,difficulty) not in go_visited and not stop:
# print(1)
try:
if not stop:
go_mase()
except IndexError:
stop=True
if position == []:
if space:
print(1)
try:
if not stop:
go_mase()
except IndexError:
stop = True
draw_maze(all_maze)
pygame.display.flip()
# FRs.tick(60)
# 获取键盘按键的名称
经过一些尝试,这是我修改后的代码:
import pygame
import sys
import json
import random
import collections
def draw_maze(maze):
for y in range(len(maze)):
for x in range(len(maze[y])):
if maze[y][x]==1:
color='blue'
elif maze[y][x]==2:
color='yellow'
elif maze[y][x]==0:
color='white'
sur = pygame.Surface((x_size, y_size))
sur.fill(pygame.color.Color(color))
sur_rect = sur.get_rect(center=(x * x_size + x_size / 2, y * y_size + y_size / 2))
screen.blit(sur, sur_rect)
def in_area(x,y):
if x>=0 and x<difficulty and y>=0 and y<difficulty+diff_add:
return True
else:
return False
def go_mase():
# print(go_position)
no_way=True
curpos=go_position.pop()
old_go_pos.insert(0,curpos)
go_visited.append(curpos)
drawing_list.insert(0,curpos)
for pos in drawing_list:
all_maze[pos[0]][pos[1]]=2
for i in range(4):
newx = curpos[0] + direction[i][0]
newy = curpos[1] + direction[i][1]
if all_maze[newx][newy]!=1 and (newx,newy) not in go_visited:
# all_maze[curpos[0]][curpos[1]] = 2
go_position.append((newx,newy))
no_way=False
if no_way:
has_change=[]
all_break=False
# print(old_go_pos)
while True:
pos=old_go_pos[0]
for i in range(4):
newx = pos[0] + direction[i][0]
newy = pos[1] + direction[i][1]
if all_maze[newx][newy] != 1 and ((newx, newy) not in go_visited) and ((newx, newy) not in has_change):
# print((newx, newy))
all_break=True
if all_break:
break
all_maze[pos[0]][pos[1]] = 0
has_change.append(pos)
old_go_pos.remove(pos)
print(old_go_pos)
print(pos)
print(drawing_list)
drawing_list.remove(pos)
def if_rect_anthor(x,y):
if (x-1)%(road_width+1) == 0 and (y-1)%(road_width+1) == 0:
return True
return False
def make_through(x1,y1,direction,maze):
_maze=maze.copy()
if direction[0] != 0:
for x in range(0,road_width+2):
for y in range(road_width):
_maze[x1+direction[0]*x][y1+y]=0
elif direction[1] != 0:
for y in range(0,road_width+2):
for x in range(road_width):
_maze[x1+x][y1+direction[1]*y]=0
return _maze
pygame.init()
road_width=4
difficulty=18
diff_add=7
difficulty=difficulty*(road_width+1)+1
diff_add=diff_add*(road_width+1)
with open('maze_record.json','w') as obj:
json.dump({'maze':[[1]*(difficulty+diff_add)]*difficulty},obj)
x_size,y_size=10,10
position=[(1,1)]
screen = pygame.display.set_mode(((difficulty+diff_add)*x_size, y_size*difficulty))
screen.fill((225,225,225))
with open('maze_record.json') as obj:
all_maze=json.load(obj)['maze']
for x in range(1,difficulty,road_width+1):
for y in range(1,difficulty+diff_add,road_width+1):
try:
# all_maze[x][y]=0
# all_maze[x+1][y]=0
# all_maze[x][y+1]=0
# all_maze[x+1][y+1]=0
for a1 in range(road_width):
for a2 in range(road_width):
all_maze[x+a1][y+a2]=0
except IndexError:
print(x,y)
old_go_pos=[]
all_maze[1][0]=0
all_maze[-2][-1]=0
direction=[[-1,0],[0,1],[1,0],[0,-1]]
visited=[]
drawing_list=[]
go_visited=[]
go_position=collections.deque()
go_position.append((1,0))
FRs=pygame.time.Clock()
stop=False
space=False
while True:
screen.fill((225,225,225))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
sys.exit()
if event.key == pygame.K_s:
with open('maze_record.json', 'w') as obj:
json.dump({'maze': [[1] * (difficulty + diff_add)] * difficulty}, obj)
if event.key==pygame.K_SPACE:
space=True
if position!=[]:
curpos=position.pop(random.randint(0,len(position)-1))
if if_rect_anthor(curpos[0],curpos[1]):
for i in range(4):
newx = curpos[0] + direction[i][0] * (road_width+1)
newy = curpos[1] + direction[i][1] * (road_width+1)
if in_area(newx,newy) and not ((newx,newy) in visited):
all_maze=make_through(curpos[0],curpos[1],direction[i],all_maze)
visited.append((newx,newy))
position.append((newx,newy))
# draw_maze(all_maze)
if position==[] and space:
try:
if not stop:
go_mase()
except IndexError:
stop=True
if position == []:
if space:
try:
if not stop:
go_mase()
except IndexError:
stop = True
draw_maze(all_maze)
pygame.display.flip()
修改前的效果图:
修改后的效果图:
你可以通过修改 road_width改变路宽,通过difficulty调整迷宫大小
代码应该比较容易看懂,同时,我还没做出相应的走迷宫算法,只能使用原来走迷宫的算法。
总之,希望你能更好的使用迷宫算法。