第13回 考える楽しさ、習う楽しさ「5.迷路を作ろう その3」

13−5 迷路を作ろう その3

その2で作られる迷路は、合格レベルのモノでしたが、落ち着いてみてみると、あることに気がつきます。
それは、単なる「点」の部分が多い、ということです。

    

ここでは、この「単なる点」の部分を減らすことを考えてみましょう。

このような単なる点ができる理由は、比較的簡単に理解できます。
この単なる点も、迷路の仕組み上、基点の1つですから、プログラム上は、順に検索されている筈ですが、そこから隣の方向をランダムで決めているため、例えば、次のような状況でも検索処理を終了してしまいます。

    

例えばこの状態で、右方向を注目、と乱数で決まれば、いくら空き方向が3つも残っている「もったいない」状況でも、検索は終わってしまいます。
そこで、この隣の空情報を徹底的に検索する方法を考えてみることにしましょう。
方法はそれほど難しくありません。最初にランダムで決めた隣方向に既にブロックが置いてあれば、別の隣に方向を変えるだけです。
ただし、この「別の隣」を決めるときに、再びランダムで決めてしまっては、あまり賢くありませんので、今回は、時計回りの方向に順に検索してみることにしました。

    

隣を決める部分、先ほどの「その2」では、このような流れになっていました。

    

ここでは、隣方向を検索する部分を追加することで、こんなフローチャートが考えられます。

    

ちょっと、複雑になりそうですが、早速プログラミングしてみましょう。
他の部分には、あまり手を加えなくてもよさそうなので、前のプログラムをできるだけ残すような形で追加変更してみました。

    Dim x as Integer
    Dim y as Integer
    Dim H as Integer
    
    Dim Dx as Integer
    Dim Dy as Integer
    
    Dim Px as Integer
    Dim Py as Integer

    Dim P as Integer

    Dim cT as Integer

    '迷路の初期化
    Call init_maze()

    'ループ1
    For x = 3 To 23 Step 2

        'ループ2
        For y = 3 To 23 Step 2
        
            'もし注目する基点に何もなければ、検索処理を行う
            If maze(x, y) = 0 Then
                
                '現在の基点を変数(Px、Py)に代入(検索の基点の初期化)
                Px = x
                Py = y
                
                '検索処理
                Do
                    'まず、基点にブロックを置く
                    Call Put_Block(Px,Py)

                    'カウンタを初期化する
                    cT = 0


                    '注目する方向の初期値をランダムで決める
                    H = Int(Rand()* 4)
                    
                    Do
                        Dx = 0
                        Dy = 0
                    
                        '注目する方向に応じた座標の増加量を決める
                        Select Case H
                            Case 0 '右(現在位置から横へ)
                                Dx = 1
                            Case 1 '下(現在位置から下へ)
                                Dy = 1
                            Case 2 '左(現在位置から左へ)
                                Dx = -1
                            Case 3 '上(現在位置から上へ)
                                Dy = -1
                        End Select                        

                        'カウンタに1加える
                        cT = cT + 1

                        'カウンタが4か、隣方向の基点がブロック以外なら方向検索から抜ける
                        If cT=4 Or maze(Px + Dx * 2, Py + Dy * 2) <> 1 Then 
                            Exit Do
                        End If

                        '次の方向をセットする(右→下→左→上)
                        H = H + 1
                        If H > 3 Then H = 0
                        
                    Loop 

                    P = maze(Px + Dx * 2, Py + Dy * 2)

                    '隣の基点がブロック以外なら
                    If P <> 1 Then

                        'まず「隣」にブロックを描く
                        Call Put_Block(Px+Dx,Py+Dy)

                        '隣の基点が外壁だったら、ここで検索処理は終わり
                        If P = 2 Then
                            Exit Do
                        End If

                        'そうでない場合、つまり何もない場合、その位置を新しい基点にする
                        '検索処理は継続される
                        Px = Px + Dx * 2
                        Py = Py + Dy * 2
                    
                    Else
                        'もう、隣方向に空きの基点が存在しない時、検索処理終了
                        Exit Do
                    End If
                Loop

            End If
        Next
    Next

更に長くなりましたが、追加された部分はわかるでしょうか?それほど多くはありませんね。
追加部分に伴って、注目する隣の方向転換した回数をチェックするために、cTというカウンタ用の変数を追加しました。
さて、早速、実行してみましょう。

    

おお!その2で作ったものより、明らかに複雑になりましたね。
むしろ、改造した手間に比べると、劇的な進化をしたような感じすらします。
もちろん、徹底的な検索のおかげで、前のものに比べると、単なる点だけのブロックが少なくなったのがよくわかりますね。
実はこの迷路ルーチン、私の3D迷路を歩くだけのアプリ「AMP」で使っているものです。
この辺りになると、実用的な迷路になると思いますが、今回は、欲張ってもう1歩先を目指してみることにしましょう。

前へ     目次へ     次へ

第13回 考える楽しさ、習う楽しさ「5.迷路を作ろう その3」