Pygameで迷路を作る
①壁と床を作る
迷路は方眼紙の様な格子状を想定。今回は下画像の様に9×9マスで作る。
迷路の周囲を全て壁にし、内側を床とする。
②柱を置く
迷路の床に1マスおきに柱を置く。
③柱から壁を伸ばす
各柱から上下左右の方向いずれかにランダムで壁を伸ばす。
運が良ければこれだけで迷路が完成するが、場合によっては入れない場所が出来る。
④入れない場所を回避する
上記問題を回避するには、最左列の柱のみ上下左右いずれかの方向に壁を伸ばし、以降の列の柱は上下右の3方向にのみ壁を作る。これにより欠陥迷路にならない。
⑤複数の正解ルートを作らない
2列目以降の柱から壁を伸ばす時、1列前の柱が伸ばした壁と重複する場合がある。この問題を防がないとゴールへの正解ルートが複数生じ迷路の難度が低下する。
壁を伸ばそうとした方向に既に壁があれば、伸ばす方向を再計算して壁の無い方向になるまで処理を繰り返す。
import pygame import sys import random WALL_COLOR = (87, 45, 24) FLOOR_COLOR = (181, 152, 132) # 床1枚の幅と高さ FLOOR_W = 48 FLOOR_H = 48 # 迷路の幅と高さ(床の枚数) MAZE_W = 9 MAZE_H = 9 # リストの宣言と初期化 maze = [] for y in range(MAZE_H): maze.append([0] * MAZE_W) # 迷路の設計情報を自動生成する def make_maze(): # 柱から伸ばす壁のに利用する値を定義 # [上, 右, 下, 左] XP = [0, 1, 0, -1] YP = [-1, 0, 1, 0] # 迷路を囲う壁を作る for x in range(MAZE_W): maze[0][x] = 1 maze[MAZE_H - 1][x] = 1 for y in range(1, MAZE_H - 1): maze[y][0] = 1 maze[y][MAZE_W - 1] = 1 # 中を何もない状態にする for y in range(1, MAZE_H - 1): for x in range(1, MAZE_W - 1): maze[y][x] = 0 # 柱を作る for y in range(2, MAZE_H - 2, 2): # range()は第三引数を2を指定し、ステップ機能で1マス飛ばししている for x in range(2, MAZE_W - 2, 2): maze[y][x] = 1 # 各柱から壁を伸ばす for y in range(2, MAZE_H - 2, 2): for x in range(2, MAZE_W - 2, 2): while True: d = random.randint(0, 3) # 変数dに柱から伸ばす方向を0~3で指定 if x > 2: # 2列目以降なら0~2(左を示す3を含めない)で左に伸ばさない d = random.randint(0, 2) if maze[y + YP[d]][x + XP[d]] == 1: # dの値が既に壁が作られた場所であればやり直し continue # 柱から伸ばす壁を示す値(変数d)を、定数YP、XPの添字に使い壁を伸ばすマス目を指定 # そのマス目を表すmaze[]に壁有りを示す1を代入 maze[y + YP[d]][x + XP[d]] = 1 break def main(): pygame.init() pygame.display.set_caption("Pygameで迷路を自動生成する") screen = pygame.display.set_mode((FLOOR_W * MAZE_W, FLOOR_H * MAZE_H)) clock = pygame.time.Clock() make_maze() while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: make_maze() # 自動生成した迷路の設計情報を使い実際に描画する for y in range(MAZE_H): for x in range(MAZE_W): W = FLOOR_W H = FLOOR_H X = x * W Y = y * H # 通路を描画 if maze[y][x] == 0: pygame.draw.rect(screen, FLOOR_COLOR, [X, Y, W, H]) # 壁を描画 if maze[y][x] == 1: pygame.draw.rect(screen, WALL_COLOR, [X, Y, W, H]) pygame.display.update() clock.tick(2) if __name__ == '__main__': main()
スペースキーを押すごとに新たな迷路が自動生成される。
下は床10×10、迷路99×99に変更した結果。
リンク
コメント
[…] ダンジョンは「棒倒し方で迷路を自動生成する」で作成した迷路を素に拡張して作る。コードの迷路作成部分の解説は「棒倒し方で迷路を自動生成する」で行っているため省略。 […]