当前位置 主页 > 网站技术 > 代码类 >

    Python迷宫生成和迷宫破解算法实例

    栏目:代码类 时间:2019-12-25 06:07

    迷宫生成

    1.随机PRIM

    思路:先让迷宫中全都是墙,不断从列表(最初只含有一个启始单元格)中选取一个单元格标记为通路,将其周围(上下左右)未访问过的单元格放入列表并标记为已访问,再随机选取该单元格与周围通路单元格(若有的话)之间的一面墙打通。重复以上步骤直到列表为空,迷宫生成完毕。这种方式生成的迷宫难度高,岔口多。

    效果:

    代码:

    import random
    import numpy as np
    from matplotlib import pyplot as plt
    
    
    def build_twist(num_rows, num_cols): # 扭曲迷宫
    	# (行坐标,列坐标,四面墙的有无&访问标记)
     m = np.zeros((num_rows, num_cols, 5), dtype=np.uint8)
     r, c = 0, 0
     trace = [(r, c)]
     while trace:
      r, c = random.choice(trace)
      m[r, c, 4] = 1	# 标记为通路
      trace.remove((r, c))
      check = []
      if c > 0:
       if m[r, c - 1, 4] == 1:
        check.append('L')
       elif m[r, c - 1, 4] == 0:
        trace.append((r, c - 1))
        m[r, c - 1, 4] = 2	# 标记为已访问
      if r > 0:
       if m[r - 1, c, 4] == 1:
        check.append('U')
       elif m[r - 1, c, 4] == 0:
        trace.append((r - 1, c))
        m[r - 1, c, 4] = 2
      if c < num_cols - 1:
       if m[r, c + 1, 4] == 1:
        check.append('R')
       elif m[r, c + 1, 4] == 0:
        trace.append((r, c + 1))
        m[r, c + 1, 4] = 2
      if r < num_rows - 1:
       if m[r + 1, c, 4] == 1:
        check.append('D')
       elif m[r + 1, c, 4] == 0:
        trace.append((r + 1, c))
        m[r + 1, c, 4] = 2
      if len(check):
       direction = random.choice(check)
       if direction == 'L':	# 打通一面墙
        m[r, c, 0] = 1
        c = c - 1
        m[r, c, 2] = 1
       if direction == 'U':
        m[r, c, 1] = 1
        r = r - 1
        m[r, c, 3] = 1
       if direction == 'R':
        m[r, c, 2] = 1
        c = c + 1
        m[r, c, 0] = 1
       if direction == 'D':
        m[r, c, 3] = 1
        r = r + 1
        m[r, c, 1] = 1
     m[0, 0, 0] = 1
     m[num_rows - 1, num_cols - 1, 2] = 1
     return m
    

    2.深度优先

    思路:从起点开始随机游走并在前进方向两侧建立墙壁,标记走过的单元格,当无路可走(周围无未访问过的单元格)时重复返回上一个格子直到有新的未访问单元格可走。最终所有单元格都被访问过后迷宫生成完毕。这种方式生成的迷宫较为简单,由一条明显但是曲折的主路径和不多的分支路径组成。

    效果:

    代码:

    def build_tortuous(num_rows, num_cols): # 曲折迷宫
     m = np.zeros((num_rows, num_cols, 5), dtype=np.uint8)
     r = 0
     c = 0
     trace = [(r, c)]
     while trace:
      m[r, c, 4] = 1	# 标记为已访问
      check = []
      if c > 0 and m[r, c - 1, 4] == 0:
       check.append('L')
      if r > 0 and m[r - 1, c, 4] == 0:
       check.append('U')
      if c < num_cols - 1 and m[r, c + 1, 4] == 0:
       check.append('R')
      if r < num_rows - 1 and m[r + 1, c, 4] == 0:
       check.append('D')
      if len(check):
       trace.append([r, c])
       direction = random.choice(check)
       if direction == 'L':
        m[r, c, 0] = 1
        c = c - 1
        m[r, c, 2] = 1
       if direction == 'U':
        m[r, c, 1] = 1
        r = r - 1
        m[r, c, 3] = 1
       if direction == 'R':
        m[r, c, 2] = 1
        c = c + 1
        m[r, c, 0] = 1
       if direction == 'D':
        m[r, c, 3] = 1
        r = r + 1
        m[r, c, 1] = 1
      else:
       r, c = trace.pop()
     m[0, 0, 0] = 1
     m[num_rows - 1, num_cols - 1, 2] = 1
     return m