參考鏈接:https://www.jianshu.com/p/f643b0a0b887
1. Randomized Prim's algorithm(隨機Prim算法)
隨機Prim算法屬於打通牆壁生成迷宮的算法,下面我將以集合的角度來描述此算法。
-
首先是初始化,建立一個所有單元格都被牆隔開的迷宮。
以8*8的迷宮為例,將每個單元格進行編號。使用集合表示路徑,集合中的元素就是單元格的編號,表示這條路徑經過了哪些單元格。
假設我們從1開始,按從左到右從上到下的順序依次對單元格進行編號。又假設迷宮的入口為左上角的單元格,編號為1,出口為右下角的單元格,編號為64。
初始化迷宮 - 所以最開始有64條路徑,每條路徑只有一個單元格。我們用
表示路徑i的集合,其中i為集合中元素的最小值(這個約定對編程來講意義不大,只是方便后面的描述)。初始時有:
- 然后隨機選擇一個內部的牆壁,假設牆壁兩邊的單元格編號為
若,表示牆壁兩邊的單元格屬於同一路徑,則沒必要打通該牆壁,之后重復步驟3.
若,表示兩單元格不在同一路徑,則打通該牆壁,連通相鄰的兩路徑,連通路徑對應為集合的合並。
之后重復步驟3。
- 直至最終合並為一個集合
,就將所有的單元格納入到一個可達路徑中,即對於入口單元格1來說其它任意單元格都是可達的。不過我們並不需要一定合並到一個集合為止,只要當
時,表明入口和出口之間已有可達路徑,就可以停止合並了。
全連通迷宮
如果編程實在沒思路可以參考下面的偽碼描述,否則可以跳過。
- 建立單元格矩陣,下標對應編號,元素值對應集合,值相同單元格代表屬於同一集合,初始時所有值都不同。
- 建立兩個向量,分別表示所有單元格的右上(也可是左下等等)牆壁,下標對應單元格,值表示牆是否被打通,初始時所有牆未被打通。
- 隨機選擇兩個向量中的一堵未被打通的牆(非邊緣),找到矩陣中此牆鄰接的兩單元格。判斷元素值是否相等,相等則不打通,然后重復當前步驟;若元素值不等,則打通該牆壁,將矩陣中兩集合的元素值統一,然后重復當前步驟。
2. Recursive backtracker ( 遞歸回溯)
同樣是屬於打通牆壁生成迷宮的算法,也叫深度優先算法(不撞南牆不回頭,哈哈)。
- 首先是初始化,建立一個所有單元格都被牆隔開的迷宮。
- 隨機選擇一個單元格作為起始點,以此單元格開始打通牆壁。
- 以當前單元格為基准,隨機選擇一個方向,若此方向的鄰接單元格沒有被訪問過,則打通這兩個單元格之間的牆壁,並將此鄰接單元格作為當前單元格,重復步驟3。
- 若當前單元格的四個鄰接單元格都已經被訪問過,則退回到進入當前單元格的鄰接單元格,且以此單元格為當前當前單元格,重復步驟3,4。
- 直到起始點單元格被退回,則算法結束。
3. Recursive division(遞歸分割法)
屬於構造牆壁生成迷宮的算法。
在空白空間隨機生成十字牆壁,將空間分割為四個子空間,然后在三面牆上各自選擇一個隨機點挖洞,保證四個子空間的連通。之后繼續對子空間做分割,直至空間不足以繼續分割為止。
引用一下別人的總結:這三種算法分別適合不同的迷宮情況,遞歸回溯適合於那種主線支線明顯的游戲(如RPG),而遞歸分割則適合轉角較少的游戲(如FPS和ACT),至於Prim,似乎適合最標准的迷宮游戲(隨機Prim算法生成的迷宮分支較多,整體上更復雜也更自然)。
作者:M_lear
鏈接:https://www.jianshu.com/p/f643b0a0b887
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。