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


參考鏈接:https://www.jianshu.com/p/f643b0a0b887

 

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 ( 遞歸回溯)

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

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

3. Recursive division(遞歸分割法)

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

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



作者:M_lear
鏈接:https://www.jianshu.com/p/f643b0a0b887
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM