java2python 发表于 2020-6-3 19:08:47

python生成迷宫

本帖最后由 java2python 于 2020-6-3 19:19 编辑

迷宫质量不论,总是迷宫吧。。。
import random

size_para =
size=*2+3,size_para*2+3]
center=//4*2+2,size//4*2+2]
map= [*size for i in range(size)]
direct = ((-2,0),(2,0),(0,2),(0,-2))
for y in range(size_para):
    for x in range(size_para):
      map = 0

step0_nodes =
map]] = 10
step1_nodes = []
while len(step0_nodes) > 0:
    node_no = random.randint(0,len(step0_nodes)-1)
    yx= step0_nodes
    for d in range(0,4):
      y=yx+direct
      x=yx+direct
      if(map == 0):
            step1_nodes.append((y,x))
            map+direct//2]+direct//2] = 10
            map = 10
    step0_nodes.pop(node_no)
    step0_nodes.extend(step1_nodes)
    step1_nodes.clear()

for y in range(1,size-1):
    str = ""
    for x in range(1,size-1):
      if map != 10:
            str = str + "#"
      else:
            str = str + " "
    print(str)
随机的,结果:
###################################################
# #   # # # # # #   #         # # # #         # #
# ##### # # # # # ### ##### ##### # # # ### # ### #
#             # # # #         #   # # # # # # # # #
############# # # # ####### ##### # # # # ##### # #
#         #   #   # # # # # # #         # # # #
######### ##### ### ### # # # # # # ######### # # #
#   # #   # # # # # #         #   # # #         #
### # ### # # # # # ####### ####### # # # #########
#   #         # #   # # # # # # # #   #   #
##### ######### ### ### # # # # # # # # ##### #####
# #   #   # # # # # #       #                     #
# ### ### # # # # # ####### ### ### # # # ### # ###
#   # # #       # # #   # # #   # # # # # # # # #
##### # # ### ### # # ### # # # ### ####### ##### #
#         # #         # # #   #   # # #   # #
### # # ### ##### ##### # # # ######### # # ##### #
#   # # #         # #             # # #   # # # # #
# # ####### ### ### ### # # # ##### # ### # # # # #
# # #       #   #       # # #   # #   #         #
# ####### # ### ### # # # ### ##### # ### ### ### #
# # #   # #   #   # # # #               #   # #
### ### # # ####### ### ### # # # # # # # #########
#       # # #       #   #   # # # # # # #       # #
##### # # ### # # ##### ### ### ####### ### # ### #
#   # # #   # # #   #   #       #   # #   #
##### ##### # # ##### # ### ### ##### # ### # # # #
#       #   # # # # # # #   #       # #   # # # # #
### # ########### # ####### # # # ##### ##### #####
#   #   #                   # # # #         #   #
###################################################

java2python 发表于 2020-6-5 20:17:15

所谓迷宫,结构上就是一棵树,没有环路,生成的方法,就是随机在图形中找一点,然后它有四个方向可以发展,这四个点加入step1_nodes,然后再把step1_nodes设回step0_nodes,再次产生候选节点,这样的话,发展节点就呈现以开始节点为中心以菱形向四周扩展的形态。那么就不是迷宫了,实际从起始点有四个候选点,他随机发展一个,以后的发展都是从step0_nodes中选取一个,发展出来的节点加入step0_nodes,当一个节点四周都是已经发展的节点了,那么这个节点就从step0_nodes删除,最后图形中找不到一个可以发展的点,所有step0_nodes的节点也被删除了,结构上就是一棵树,也就是迷宫(有所不同的是,迷宫的任何一个节点都可以作为根),设定一个起点,一个终点。

查找就简单了,就是从出发点发展,这次不是造迷宫,可以用菱形扩散法,也就是广度优先。

图形演示,图一是图中查找过程,图二是查找出的结果线路
和八皇后一样框架,这个程序的话,其中下面两句尤为重要,因为真的是画了很多线,虽然都很短,画完后,保存到图像,以后直接作为背景使用:

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

import pygame
import sys
import os
import random
import time
from pygame.locals import *
import tkinter as tk
from tkinter import *
import tkinter.messagebox# 要使用messagebox先要导入模块

class Maze:
    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+Maze.direct]+Maze.direct] == 0):
                return True
      return False
    @staticmethod
    def create_maze(size_para):
      WAY = 1
      size=*2+3,size_para*2+3]
      Maze.size = size
      direct = Maze.direct
      center=-1)//2*2,random.randint(1,size-1)//2*2]
      map= [*size for i in range(size)]
      for y in range(size_para):
            for x in range(size_para):
                map = 0
      step0_nodes =
      map]] = WAY
      step1_nodes = []

      while len(step0_nodes) > 0:
            node_no = random.randint(0,len(step0_nodes)-1)
            yx= step0_nodes
            if not Maze.check_move(map,yx):
                step0_nodes.pop(node_no)
                continue
            direct_start = random.randint(0,3)
            for d in range(direct_start,direct_start+4):
                y=yx+direct
                x=yx+direct
                if(map == 0):
                  step1_nodes.append((y,x))
                  map+direct//2]+direct//2] = WAY
                  map = WAY
                  break
            step0_nodes.extend(step1_nodes)
            step1_nodes.clear()
      Maze.map = map

    @staticmethod
    def solve_maze(startY,endYX):
      WAY = 1
      direct = Maze.direct
      center=(startY*2+2,2,-1)
      map = Maze.map
      steps_nodes = []
      step0_nodes =
      map]] = 0
      step1_nodes = []

      while len(step0_nodes) > 0:
            steps_nodes.append(step0_nodes)
            for n in range(0,len(step0_nodes)):
                yx= step0_nodes
                for d in range(0,4):
                  y=yx+direct
                  x=yx+direct
                  y3=yx+direct//2
                  x3=yx+direct//2
                  if(map != 100 and map == WAY ):
                        step1_nodes.append((y,x,n))
                        map+direct]+direct] = 0
                        if y == endYX*2 and x== endYX*2:
                            steps_nodes.append(step1_nodes)
                            return steps_nodes
            step0_nodes = step1_nodes[:]
            step1_nodes.clear()
      return None

class CMG: #画面显示管理
    screen = None
    map = None
    gameAnswer = None
    WHITE = (255, 255, 255)
    GREEN = (0, 255, 0)
    RED = (255, 0, 0)
    BLUE = (0, 0, 255)
    blocksize = 0
    step = 0
    back_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 = gameAnswer
            if 800//len(map) > 570//len(map):
                CMG.blocksize = 570//len(map)
            else:
                CMG.blocksize = 800//len(map)
      #如果存在对象成员
      self.init_game_info()

    def init_game_info(self):
      pass

    def printAll(self):
      if CMG.step > len(CMG.gameAnswer):
            return
      CMG.screen.fill((0, 0, 0))
      size = Maze.size
      if CMG.back_ground == None:
            for y in range(1,size-1):
                for x in range(1,size-1):
                  val = CMG.map
                  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 - 1
            step_node = CMG.gameAnswer
            yx = step_node
            while(yx!=-1):
                y = yx
                x = yx
                step -= 1
                step_node = CMG.gameAnswer
                yx = step_node]
                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
            for s in range(0,len(step_node)):
                yx = step_node
                y = yx
                x = yx
                #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 += 1

    def moveAll(self):
      pass

#------------------------------------------------
#tkinter,pygame混合区 START
#------------------------------------------------
root = tk.Tk()
root.resizable(0,0)

embed = tk.Frame(root, width = 800, height = 570) #creates embed frame for pygame 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,因此全部打包
class PARAM:
    STATUS = 0
    TICK_NORMAL = 5

#按钮动作区 =====================================
def exit_game():
    global param
    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()
steps_nodes = Maze.solve_maze(0,(49,69))
param.cmg = CMG(screen,Maze.map,steps_nodes)
#------------------------------------------------
#主函数,使用pygame框架,无限LOOP对各种事件然后相应处理
#------------------------------------------------
def main():
    global param
    #pygame.mixer.music.play(-1)
    clock = pygame.time.Clock()

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

      #画面按钮按下后,修改param.STATUS,实际动作这里实现
      ifparam.STATUS == 100:
            #退出按钮
            if tk.messagebox.askokcancel('提示', '要退出画面吗'):
                break
            param.STATUS = 0
      elif param.STATUS == 10:
            pass
            
      param.cmg.printAll()

      #显示游戏画面
      pygame.display.flip()
      #设置帧率:长期画面不操作,设置成最闲
      clock.tick(param.TICK_NORMAL)
            
      root.update()

main()

14-15python 发表于 2024-5-8 18:47:48

大佬,我的论文可以引用你的代码吗,你是否有什么名字我可以把你加上去
页: [1]
查看完整版本: python生成迷宫