迷路生成のアルゴリズム
迷路生成のアルゴリズムは数多くあります。
Maze Classification -Maze Creation Algorithms
迷路生成の各種アルゴリズムのC++実装 (Win/Mac両対応)
最も簡単と言われる棒倒し法で迷路を作成してみます。
棒倒し法
棒倒し法は、四方を壁に囲まれた四角形の中で、1マス置きに棒を立てて、その棒をランダムに倒していくことで壁を作り、結果として迷路ができあがるようなイメージです。
あまり複雑な迷路を作ることはできないそうです。
下のサイトはどれも説明が上手です。
また、ドットインストールでは、javascirptで、棒倒し法による迷路作成を解説していました。
https://dotinstall.com/lessons/maze_js
pythonで実装してみる
import random class Maze(): """ 迷路を作るクラス""" PATH = 0 WALL = 1 def __init__(self, width, height): self.maze = [] self.width = width self.height = height # 迷路は、幅高さ5以上の奇数で生成する。 if(self.height < 5 or self.width < 5): print('at least 5') exit() if (self.width % 2) == 0: self.width += 1 if (self.height % 2) == 0: self.height += 1 def set_out_wall(self): """ 迷路全体を構成する2次元配列、迷路の外周を壁とし、それ以外を通路とする。""" for _x in range(0, self.width): row = [] for _y in range(0, self.height): if (_x == 0 or _y == 0 or _x == self.width-1 or _y == self.height -1): cell = self.WALL else: cell = self.PATH row.append(cell) self.maze.append(row) return self.maze def set_inner_wall_boutaosi(self): """迷路の中に棒を立ててランダムな方向に倒す。 外周の内側に基準となる棒を1セルおき、(x, y ともに偶数の座標)に配置する。""" for _x in range(2, self.width-1, 2): for _y in range(2, self.height-1, 2): self.maze[_x][_y] = self.WALL # 棒をランダムな方向に倒して壁とする。 # (ただし以下に当てはまる方向以外に倒す。) # 1行目の内側の壁以外では上方向に倒してはいけない。 # すでに棒が倒され壁になっている場合、その方向には倒してはいけない。 while True: if _y == 2: direction = random.randrange(0, 4) else: direction = random.randrange(0, 3) # 棒を倒して壁にする方向を決める。 wall_x = _x wall_y = _y # 右 if direction == 0: wall_x += 1 # 下 elif direction == 1: wall_y += 1 # 左 elif direction == 2: wall_x -= 1 # 上 else: wall_y -= 1 # 壁にする方向が壁でない場合は壁にする。 if self.maze[wall_x][wall_y] != self.WALL: self.maze[wall_x][wall_y] = self.WALL break return self.maze def set_start_goal(self): """ スタートとゴールを迷路にいれる。""" self.maze[1][1] = 'S' self.maze[self.width-2][self.height-2] = 'G' return self.maze def print_maze(self): """ 迷路を出力する。""" for row in self.maze: for cell in row: if cell == self.PATH: print(' ', end='') elif cell == self.WALL: print('###', end='') elif cell == 'S': print('STR', end='') elif cell == 'G': print('GOL', end='') print() maze = Maze(20, 20) maze.set_out_wall() maze.set_inner_wall_boutaosi() maze.set_start_goal() maze.print_maze()
以下では、穴掘り法による迷路生成を行っています。