【Python】迷路のスタートからの距離を出力する

スタートからの距離と壁を距離の最大値の桁数に合わせて出力する。

import sys
import random
from collections import deque

class Maze:
  PATH = 0
  WALL = 1

  def __init__(self, width, height, seed=0):
    self.width = width
    self.height = height
    if self.width < 5 or self.height < 5:
      sys.exit()
    if self.width % 2 == 0:
      self.width += 1
    if self.height % 2 == 0:
      self.height += 1
    self.maze = [[self.PATH for x in range(self.width)] for y in range(self.height)]
    self.dist = [[-1 for i in range(self.width)] for j in range(self.height)]
    self.start = [1, 1]
    self.goal = [self.width-2, self.height-2]
    random.seed(seed)

  def set_outer_wall(self):
    for y in range(0, self.height):
      for x in range(0, self.width):
        if x == 0 or y == 0 or x == self.width-1 or y == self.height-1:
          self.maze[y][x] = self.WALL
    return self.maze

  def set_inner_wall(self):
    for y in range(2, self.height-1, 2):
      for x in range(2, self.width-1, 2):
        self.maze[y][x] = self.WALL
    return self.maze

  def set_maze_boutaoshi(self):
    self.set_outer_wall()
    self.set_inner_wall()
    for y in range(2, self.height-1, 2):
      for x in range(2, self.width-1, 2):
        while True:
          wall_x = x
          wall_y = y
          if y == 2:
            direction = random.randrange(0, 4)
          else:
            direction = random.randrange(0, 3)
          if direction == 0:
            wall_x += 1
          elif direction == 1:
            wall_y += 1
          elif direction == 2:
            wall_x -= 1
          elif direction == 3:
            wall_y -= 1
          if self.maze[wall_y][wall_x] != self.WALL:
            self.maze[wall_y][wall_x] = self.WALL
            break
    return self.maze

  def set_start_goal(self, start, goal):
    if self.maze[start[1]][start[0]] == self.PATH:
      self.start = start
    if self.maze[goal[1]][goal[0]] == self.PATH:
      self.goal = goal
    return self.maze

  def set_dist_bfs(self,flag=False):
    queue = deque()
    self.dist[self.start[1]][self.start[0]] = 0
    queue.append(self.start)
    while len(queue) > 0:
      point = queue.popleft()
      for x in [[0,-1],[1,0],[0,1],[-1,0]]:
        if self.maze[point[1]+x[1]][point[0]+x[0]] == 0 and self.dist[point[1]+x[1]][point[0]+x[0]] == -1:
          self.dist[point[1]+x[1]][point[0]+x[0]] = self.dist[point[1]][point[0]] + 1
          queue.append([point[0]+x[0],point[1]+x[1]])
        if flag != True:
          if point[0]+x[0] == self.goal[0] and point[1]+x[1] == self.goal[1]:
            queue.clear()
            break
    return self.dist

  def set_dist_dfs(self,flag=False):
    stack = deque()
    self.dist[self.start[1]][self.start[0]] = 0
    stack.append(self.start)
    while len(stack) > 0:
      point = stack.pop()
      for x in [[0,-1],[1,0],[0,1],[-1,0]]:
        if self.maze[point[1]+x[1]][point[0]+x[0]] == 0 and self.dist[point[1]+x[1]][point[0]+x[0]] == -1:
          self.dist[point[1]+x[1]][point[0]+x[0]] = self.dist[point[1]][point[0]] + 1
          stack.append([point[0]+x[0],point[1]+x[1]])
        if flag != True:
          if point[0]+x[0] == self.goal[0] and point[1]+x[1] == self.goal[1]:
            stack.clear()
            break
    return self.dist

  def set_shortest_path(self):
    point = self.goal
    self.maze[point[1]][point[0]] = '*'
    while self.dist[point[1]][point[0]] > 0:
      for x in [[0,-1],[1,0],[0,1],[-1,0]]:
        if self.dist[point[1]][point[0]]-self.dist[point[1]+x[1]][point[0]+x[0]] == 1:
          if self.dist[point[1]][point[0]] > 0:
            self.maze[point[1]+x[1]][point[0]+x[0]] = '*'
            point = [point[0]+x[0],point[1]+x[1]]
    return self.maze

  def print_maze(self):
    self.maze[self.start[1]][self.start[0]] = 'S'
    self.maze[self.goal[1]][self.goal[0]] = 'G'
    for col in self.maze:
      for cell in col:
        if cell == self.WALL:
          print('#', end='')
        elif cell == self.PATH:
          print(' ', end='')
        elif cell == 'S':
          print('S', end='')
        elif cell == 'G':
          print('G', end='')
        elif cell == '*':
          print('*', end='')
      print()

  def print_dist(self):
    for col in self.dist:
      for cell in col:
        if cell == -1:
          if max(map(lambda x: max(x), self.dist)) == -1:
            print('#', end='')
          else:
            for i in range(len(str(max(map(lambda x: max(x), self.dist))))):
              print('#', end='')
        else:
          if len(str(cell)) == len(str(max(map(lambda x: max(x), self.dist)))):
            print(cell, end='')
          else:
            for i in range(len(str(max(map(lambda x: max(x), self.dist))))-len(str(cell))):
              print(' ', end='')
            print(cell, end='')
      print()

maze1 = Maze(15, 15)
maze1.set_maze_boutaoshi()
maze1.set_start_goal([5, 5], [9, 11])
maze1.set_dist_bfs(1)
maze1.print_dist()

今回は、以下のように出力される。

##############################
##12##10## 8 910## 8##141312##
##11## 9## 7###### 7######11##
##10 9 8 7 6 5 4 5 6 7 8 910##
##11## 9###### 3##########11##
##12##10## 0 1 2 3 4 5 6##12##
##13######################13##
##1415161718##20191817161514##
##15######19##########17##15##
##161718##2021222324##18##16##
######19######23##25######17##
##2221202122##24##26##201918##
######21######25######21##19##
##2423222324######242322##20##
##############################
タイトルとURLをコピーしました