[轉]三種迷宮生成算法概述

參考連接:https://www.jianshu.com/p/f643b0a0b887web

 

1. Randomized Prim's algorithm(隨機Prim算法)

隨機Prim算法屬於打通牆壁生成迷宮的算法,下面我將以集合的角度來描述此算法。算法

  1. 首先是初始化,創建一個全部單元格都被牆隔開的迷宮。
    以8*8的迷宮爲例,將每一個單元格進行編號。使用集合表示路徑,集合中的元素就是單元格的編號,表示這條路徑通過了哪些單元格。
    假設咱們從1開始,按從左到右從上到下的順序依次對單元格進行編號。又假設迷宮的入口爲左上角的單元格,編號爲1,出口爲右下角的單元格,編號爲64。編程


     
    初始化迷宮
  2. 因此最開始有64條路徑,每條路徑只有一個單元格。咱們用P_{i}表示路徑i的集合,其中i爲集合中元素的最小值(這個約定對編程來說意義不大,只是方便後面的描述)。初始時有:P_{1}=\{1\},P_{2}=\{2\},\cdots,P_{64}=\{64\}
  3. 而後隨機選擇一個內部的牆壁,假設牆壁兩邊的單元格編號爲i,j,i\in P_{m},j\in P_{n}
    m=n,表示牆壁兩邊的單元格屬於同一路徑,則不必打通該牆壁,以後重複步驟3.
    m\ne n,表示兩單元格不在同一路徑,則打通該牆壁,連通相鄰的兩路徑,連通路徑對應爲集合的合併。P_{min(m,n)}=P_{m}\cup P_{n}以後重複步驟3。
  4. 直至最終合併爲一個集合P_{1}=\{1,2,\cdots,64\},就將全部的單元格歸入到一個可達路徑中,即對於入口單元格1來講其它任意單元格都是可達的。不過咱們並不須要必定合併到一個集合爲止,只要當1,64\in P_{1}時,代表入口和出口之間已有可達路徑,就能夠中止合併了。
     
    全連通迷宮

    若是編程實在沒思路能夠參考下面的僞碼描述,不然能夠跳過。
  • 創建單元格矩陣,下標對應編號,元素值對應集合,值相同單元格表明屬於同一集合,初始時全部值都不一樣。
  • 創建兩個向量,分別表示全部單元格的右上(也但是左下等等)牆壁,下標對應單元格,值表示牆是否被打通,初始時全部牆未被打通。
  • 隨機選擇兩個向量中的一堵未被打通的牆(非邊緣),找到矩陣中此牆鄰接的兩單元格。判斷元素值是否相等,相等則不打通,而後重複當前步驟;若元素值不等,則打通該牆壁,將矩陣中兩集合的元素值統一,而後重複當前步驟。

2. Recursive backtracker ( 遞歸回溯)

一樣是屬於打通牆壁生成迷宮的算法,也叫深度優先算法(不撞南牆不回頭,哈哈)。dom

  1. 首先是初始化,創建一個全部單元格都被牆隔開的迷宮。
  2. 隨機選擇一個單元格做爲起始點,以此單元格開始打通牆壁。
  3. 以當前單元格爲基準,隨機選擇一個方向,若此方向的鄰接單元格沒有被訪問過,則打通這兩個單元格之間的牆壁,並將此鄰接單元格做爲當前單元格,重複步驟3。
  4. 若當前單元格的四個鄰接單元格都已經被訪問過,則退回到進入當前單元格的鄰接單元格,且以此單元格爲當前當前單元格,重複步驟3,4。
  5. 直到起始點單元格被退回,則算法結束。

3. Recursive division(遞歸分割法)

屬於構造牆壁生成迷宮的算法。
在空白空間隨機生成十字牆壁,將空間分割爲四個子空間,而後在三面牆上各自選擇一個隨機點挖洞,保證四個子空間的連通。以後繼續對子空間作分割,直至空間不足以繼續分割爲止。orm

引用一下別人的總結:這三種算法分別適合不一樣的迷宮狀況,遞歸回溯適合於那種主線支線明顯的遊戲(如RPG),而遞歸分割則適合轉角較少的遊戲(如FPS和ACT),至於Prim,彷佛適合最標準的迷宮遊戲(隨機Prim算法生成的迷宮分支較多,總體上更復雜也更天然)。遞歸

做者:M_lear 連接:https://www.jianshu.com/p/f643b0a0b887 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。
相關文章
相關標籤/搜索