可定义道路宽度的迷宫生成算法

我在一年前学习了迷宫生成算法,非常惊讶。在自己实现的时候,由于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调整迷宫大小

代码应该比较容易看懂,同时,我还没做出相应的走迷宫算法,只能使用原来走迷宫的算法。

总之,希望你能更好的使用迷宫算法。 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值