python解图片迷宫生成路径_python:迷宫生成,搜索(广度优先),图形界面演示搜索过程...

import pygame

import sys

import os

import random

import timefrom pygame.locals import *import tkinterastkfrom tkinter import *import tkinter.messagebox # 要使用messagebox先要导入模块classMaze:

size=None

print_str=(('##',' '),('#',' '))

map=None

direct= ((-2,0),(2,0),(0,2),(0,-2),(-2,0),(2,0),(0,2))

@staticmethod

def check_move(map,yx):for d in range(0,4):if(map[yx[0]+Maze.direct[d][0]][yx[1]+Maze.direct[d][1]] == 0):returnTruereturnFalse

@staticmethod

def create_maze(size_para):

WAY= 1size=[size_para[0]*2+3,size_para[1]*2+3]

Maze.size=size

direct=Maze.direct

center=[random.randint(1,size[0]-1)//2*2,random.randint(1,size[1]-1)//2*2]

map= [[100]*size[1] for i in range(size[0])]for y in range(size_para[0]):for x in range(size_para[1]):

map[2*y+2][2*x+2] = 0step0_nodes=[center]

map[center[0]][center[1]] =WAY

step1_nodes=[]while len(step0_nodes) > 0:

node_no= random.randint(0,len(step0_nodes)-1)

yx=step0_nodes[node_no]ifnot Maze.check_move(map,yx):

step0_nodes.pop(node_no)continuedirect_start= random.randint(0,3)for d in range(direct_start,direct_start+4):

y=yx[0]+direct[d][0]

x=yx[1]+direct[d][1]if(map[y][x] == 0):

step1_nodes.append((y,x))

map[yx[0]+direct[d][0]//2][yx[1]+direct[d][1]//2] = WAY

map[y][x] =WAYbreakstep0_nodes.extend(step1_nodes)

step1_nodes.clear()

Maze.map=map

@staticmethod

def solve_maze(startY,endYX):

WAY= 1direct=Maze.direct

center=(startY*2+2,2,-1)

map=Maze.map

steps_nodes=[]

step0_nodes=[center]

map[center[0]][center[1]] = 0step1_nodes=[]while len(step0_nodes) > 0:

steps_nodes.append(step0_nodes)for n in range(0,len(step0_nodes)):

yx=step0_nodes[n]for d in range(0,4):

y=yx[0]+direct[d][0]

x=yx[1]+direct[d][1]

y3=yx[0]+direct[d][0]//2

x3=yx[1]+direct[d][1]//2

if(map[y3][x3] != 100 and map[y][x] ==WAY ):

step1_nodes.append((y,x,n))

map[yx[0]+direct[d][0]][yx[1]+direct[d][1]] = 0

if y == endYX[0]*2 and x== endYX[1]*2:

steps_nodes.append(step1_nodes)returnsteps_nodes

step0_nodes=step1_nodes[:]

step1_nodes.clear()returnNoneclassCMG: #画面显示管理

screen=None

map=None

gameAnswer=None

WHITE= (255, 255, 255)

GREEN= (0, 255, 0)

RED= (255, 0, 0)

BLUE= (0, 0, 255)

blocksize= 0step= 0back_ground=None

def __init__(self,screen,map,gameAnswer):if CMG.screen ==None:

#print("#############OS.PATH=%s"%os.path.dirname(os.path.abspath(__file__)))

CMG.screen=screen

CMG.map=map

CMG.gameAnswer=gameAnswerif 800//len(map[0]) > 570//len(map):

CMG.blocksize = 570//len(map)

else:

CMG.blocksize= 800//len(map[0])

#如果存在对象成员

self.init_game_info()

def init_game_info(self):

pass

def printAll(self):if CMG.step >len(CMG.gameAnswer):returnCMG.screen.fill((0, 0, 0))

size=Maze.sizeif CMG.back_ground ==None:for y in range(1,size[0]-1):for x in range(1,size[1]-1):

val=CMG.map[y][x]if y%2==1 and x%2==0 and val == 100:

#start_pos= [(y*CMG.blocksize,x*CMG.blocksize)]

end_pos= [((x-1)*CMG.blocksize,y*CMG.blocksize),((x+1)*CMG.blocksize,y*CMG.blocksize)]

pygame.draw.lines(CMG.screen, CMG.GREEN,0 , end_pos, 2)

elif y%2==0 and x%2==1 and val == 100:

end_pos= [(x*CMG.blocksize,(y-1)*CMG.blocksize),(x*CMG.blocksize,(y+1)*CMG.blocksize)]

pygame.draw.lines(CMG.screen, CMG.GREEN,0 , end_pos, 2)

select_rect= CMG.screen.subsurface(0,0,800,570)

CMG.back_ground=select_rect.copy()else:

self.screen.blit(CMG.back_ground,(0,0))if CMG.step ==len(CMG.gameAnswer):

step= CMG.step - 1step_node=CMG.gameAnswer[step]

yx= step_node[len(step_node)-1]while(yx[2]!=-1):

y= yx[0]

x= yx[1]

step-= 1step_node=CMG.gameAnswer[step]

yx= step_node[yx[2]]

pygame.draw.rect(CMG.screen, CMG.WHITE, (((x-1)*CMG.blocksize+2,(y-1)*CMG.blocksize+2), (CMG.blocksize*2-4, CMG.blocksize*2-4)), 0)else:

step_node=CMG.gameAnswer[CMG.step]for s in range(0,len(step_node)):

yx=step_node[s]

y= yx[0]

x= yx[1]

#pygame.draw.rect(background, (0, 255, 0), ((200, 5), (100, 100)), 3)

pygame.draw.rect(CMG.screen, CMG.WHITE, (((x-1)*CMG.blocksize+2,(y-1)*CMG.blocksize+2), (CMG.blocksize*2-4, CMG.blocksize*2-4)), 0)

CMG.step+= 1def moveAll(self):

pass

#------------------------------------------------#tkinter,pygame混合区 START

#------------------------------------------------root=tk.Tk()

root.resizable(0,0)

embed= tk.Frame(root, width = 800, height = 570) #creates embed frame forpygame window

embed.grid(columnspan= (800), rowspan = 730) # Adds grid

embed.pack(side=TOP) #packs window to the left

buttonwin= tk.Frame(root, width = 800, height = 150)

buttonwin.pack(side=BOTTOM)

os.environ['SDL_WINDOWID'] =str(embed.winfo_id())

os.environ['SDL_VIDEODRIVER'] = 'windib'screen= pygame.display.set_mode((800,570))

#pygame.init()

pygame.display.init()

pygame.mixer.init()

#------------------------------------------------#tkinter,pygame混合区 END

#------------------------------------------------#参数,因为函数内要使用之外的变量,需要globe,因此全部打包classPARAM:

STATUS= 0TICK_NORMAL= 5#按钮动作区=====================================def exit_game():globalparam

param.STATUS= 100#控件定义区=====================================button_exit_b= Button(buttonwin,text = '退出画面', width=7, command=exit_game)

button_exit_b.place(x=740,y=100)

#状态,参数,循环中使用,比如STATUS=0:初次进入,1:...100:退出

param=PARAM()

Maze.create_maze([30,50])

steps_nodes= Maze.solve_maze(0,(25,49))

param.cmg=CMG(screen,Maze.map,steps_nodes)

#------------------------------------------------#主函数,使用pygame框架,无限LOOP对各种事件然后相应处理

#------------------------------------------------def main():globalparam

#pygame.mixer.music.play(-1)

clock=pygame.time.Clock()whileTrue:

#这段event代码是必须的,哪怕在这个程序中不需要,不执行的话整个框架转不动for event in pygame.event.get():if event.type ==QUIT:

sys.exit()

#画面按钮按下后,修改param.STATUS,实际动作这里实现if param.STATUS == 100:

#退出按钮if tk.messagebox.askokcancel('提示', '要退出画面吗'):breakparam.STATUS= 0elif param.STATUS== 10:

pass

param.cmg.printAll()

#显示游戏画面

pygame.display.flip()

#设置帧率:长期画面不操作,设置成最闲

clock.tick(param.TICK_NORMAL)

root.update()

main()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值