迷路自動生成アルゴリズム

この記事はUnityゲームプログラミングバイブルの内容を解説しています
https://www.amazon.co.jp/Unity%E3%82%B2%E3%83%BC%E3%83%A0-%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%83%BB%E3%83%90%E3%82%A4%E3%83%96%E3%83%AB-%E5%90%89%E8%B0%B7-%E5%B9%B9%E4%BA%BA/dp/4862464130

#迷路自動生成アルゴリズム
今回は迷路などを入る度ランダムに生成するアルゴリズムについて話します
これによりゲームの繰り返しを避け飽きさせなくします

##アルゴリズム
今回紹介するやり方は壁を作り部屋を作るというよりは
一面壁のフィールドに穴を掘っていくことで迷路を作ります

![迷路アルゴリズム.png](https://qiita-image-store.s3.amazonaws.com/0/251313/f6f86669-dab9-d4ac-970e-a392698eec01.png)

今回用いるアルゴリズムはマップの広さを奇数×奇数としたときのみ可能です
まずはランダムに奇数番目×奇数番目のマスを選択します（配列上では偶数×偶数番目）
今回は3×3番目の真ん中のマスを使おうと思います

###1-1　スタート地点
まずはスタート地点の壁を掘り白くします
ここから穴を掘るルールを決めます
>掘った穴から上下左右に2マス先を判定し壁があれば黒い矢印
2マス先に壁がなければ青い矢印にします

![迷路アルゴリズム2.png](https://qiita-image-store.s3.amazonaws.com/0/251313/344b3588-e6ee-5b10-d6b4-522122f42be4.png)

###1-2　掘る
黒い矢印の中から1つをランダムに選びその方向の壁を2マス掘る
![迷路アルゴリズム3.png](https://qiita-image-store.s3.amazonaws.com/0/251313/785fb5eb-151b-6093-d2ca-9379c4d4d41f.png)
###1-3　掘り進める
掘り進めた先のマス今回であれば上から1番目横に3番目のマスから
再び矢印をだし黒い矢印が出なくなるまで繰り返します

![迷路アルゴリズム4.png](https://qiita-image-store.s3.amazonaws.com/0/251313/f6860790-254c-90d9-642d-420e39003aa3.png)
上にもう進むマスがない、下方向には2マス先に壁がないので青い矢印になり左右だけ
黒い矢印がでます
![迷路アルゴリズム5.png](https://qiita-image-store.s3.amazonaws.com/0/251313/300831b2-fae2-3689-e54a-c6e6d51de09a.png)
右方向をランダムに選んだとしたとき上のような図になります

###1-4　最終形態
進んだマスから出る矢印がすべて青になった時終了し、その結果
![迷路アルゴリズム6.png](https://qiita-image-store.s3.amazonaws.com/0/251313/d29a9fbc-f550-79d5-e724-6714e64c904e.png)
自動でこのようなマップができました
ここまではイメージ図なので実際にゲームにマップを作る時を考えましょう
###1-5　ゲームに適応
まずはこのマップのマス目に数字をつけましょう
>スタート地点を２、ゴールを３、壁を０、掘った後は１にしましょう

![迷路アルゴリズム7.png](https://qiita-image-store.s3.amazonaws.com/0/251313/54f68bec-e79b-563e-ea22-ed896276b739.png)

この数字を配列に直し**数字に対応したオブジェクト**を置いていくことで迷路となります

##2　不思議のダンジョンのような部屋のあるダンジョン制作
先ほど紹介したものはあくまで迷路でありただ進むだけです
そこで先ほどのアルゴリズムに工夫を加えてダンジョンっぽくしていきたいと思います
###2-1　壁の用意
さきほど同様ップの広さを奇数×奇数としスタートの場所の選び方も同様にし
真ん中からスタートします
今回は壁を掘る際のルールを変更し
>黒い矢印をそれぞれランダムにtrueとfalseにわけ
trueなら赤い矢印で壁を掘りfalseなら青い矢印で１マス横を黒く塗りつぶします
黒い矢印の条件は1マス先に壁があり壁が黒でないこととする

![迷路アルゴリズム2.png](https://qiita-image-store.s3.amazonaws.com/0/251313/62018e13-ae48-6757-a0fb-2d0c02bbfa72.png)
###2-2　掘る
今回は上と右側をtrue、下と左をfalseとすると
![迷路アルゴリズム7-1.png](https://qiita-image-store.s3.amazonaws.com/0/251313/f48e1223-b5e4-5ba7-4f94-7632eb8a2e71.png)
このように掘り進めることができまた黒いマスもできます

###2-3　掘り進める
そして先ほど同様掘った先のマスを基準に同じことを繰り返します
![迷路アルゴリズム8.png](https://qiita-image-store.s3.amazonaws.com/0/251313/137a2e74-9c75-53cf-89a4-6ddd50135cf0.png)
壁のない場所は矢印が青くなりもともとfalseになります
3×1のマスの左右の矢印がfalse
5×3のマスの上下の矢印がtrueになったとすると
![迷路アルゴリズム9.png](https://qiita-image-store.s3.amazonaws.com/0/251313/58d8c006-a7bb-0742-9642-295187e1c38f.png)
このように掘り進めることができます
###2-4　最終形態
この動作を繰り返した結果以下のようになります（なったと仮定）
![迷路アルゴリズム10.png](https://qiita-image-store.s3.amazonaws.com/0/251313/5a7adde3-07e6-2303-03ee-744444fb3ebb.png)
###2-5　ゲームに適応
>スタート地点を２、ゴールを５、壁を０

ここまでは同じですがダンジョン風にするために
通路と部屋で分けます
矢印の判定をし、赤い矢印で壁を掘った時に2マス先を３、1マス先を１として
>３を部屋、１を通路、黒い壁を４とする

数字に適応させマップにつけたのが
![迷路アルゴリズム11.png](https://qiita-image-store.s3.amazonaws.com/0/251313/7e3f48fc-1edc-7f5b-63bd-f3edea2157fa.png)

となる
この数字を配列に直し**数字に対応したオブジェクト**を置いていくことで迷路となります
>０と４を壁、１を通路、２をスタート地点、３を部屋、５をゴールとする

![迷路アルゴリズム12.png](https://qiita-image-store.s3.amazonaws.com/0/251313/37fc5ab5-19c1-0063-ee63-269b8c12dac0.png)

###2-6　補足説明
####黒い壁を増やした理由
一度判定した道を再度判定し直さないようにするため