top
おさだのホームページ

迷路制作(5)アルゴリズム[2]の実装と幅優先探索
前回書いたアーキテクチャに肉付けをする

アルゴリズム[2]の実装

前回書いたクラスのmake_mairo()関数の中身を埋めていく。

アルゴリズム[2]は、一本の道をランダムに伸ばしていき、端に到達したら一個戻って道が作れるか判定する。 もし道が作れるのならばまたそこから道を伸ばし、道が作れないのならばさらに一個戻ることを繰り返すことで迷路を作成するものである。

実装はまず、道を0、壁を1とした2次元配列を作り、行を縦座標、列を横座標と考えてアプリ画面に描画を行う。
0と1で構成される2次元配列を生成する関数make_meiro()を書いた。

copy
make_meiro()
# make_meiro(ny=開始位置のy座標, nx=開始位置のx座標, mairo=全要素が1の2次元配列)

def make_meiro(self, ny, nx, meiro) -> list:
    array = list(range(4))
    random.shuffle(array)
    
    for i in array:
        if(ny+self.dy[i][1] < 1) or (ny+self.dy[i][1] >= self.height):
            continue
        if(nx+self.dx[i][1] < 1) or (nx+self.dx[i][1] >= self.width):
            continue
        if not meiro[ny+self.dy[i][1]][nx+self.dx[i][1]]:
            continue
        for j in range(2):
            meiro[ny+self.dy[i][j]][nx+self.dx[i][j]] = 0
        meiro = self.make_meiro(ny+self.dy[i][1], nx+self.dx[i][1], meiro)
    
    return meiro

この2次元配列のうち、値が1である座標に壁を設置する関数put_block()も書いた。
copy
put_block()
def put_block(self):
    self.walls = deque()
    meiro = [[1]*self.width for _ in range(self.height)]
    meiro[1][1] = 0
    meiro = self.make_meiro(self.x1, self.y1, meiro)
    for y, ms in enumerate(meiro[1:self.height-1]):
        ms = ms[1:self.width-1]
        for x, m in enumerate(ms):
            if m:
                self.canvas.create_rectangle(25*x + self.pad[0],
                                             25*y + self.pad[1],
                                             25*(x+1) + self.pad[0],
                                             25*(y+1) + self.pad[1],
                                             tag="wall", fill="#000000", outline="#000000")
                self.walls.append([x, y])