canvas——隨機生成迷宮


先上圖。

效果

代碼

隨機生成迷宮要求任意兩點都能夠找到相同的路徑,也就是說,迷宮是一個連通圖。隨機生成迷宮可以使用普里姆算法、廣度優先算法、深度優先算法等實現。這里將使用普里姆算法通過生成最小數的方法,實現迷宮圖。

初始迷宮

迷宮有路和牆,白色表示路,黑色表示牆。每一個格子代表一個頂點,這里一共有100個頂點,需要找出99條邊,使頂點連接起來,也就是要打通99塊牆。

迷宮使用二位數組保存,為迷宮指定路的行數和列數,生成初始數組。

普利姆算法不了解的話,可以參考這篇博客的解析。

 
         
/*
* this.r 路的行數
* this.c 路的列數
* this.arr 保存迷宮的二維數組
*/
initArray() {
    for(let i = 0; i < 2 * this.r + 1; ++i) {
        this.arr[i] = [];
        for(let n = 0; n < 2 * this.c + 1; ++n) {
            if((n ^ (n - 1)) === 1 && (i ^ (i - 1)) === 1) {
                this.arr[i][n] = 0;                   // 0 表示路
                this.notAccessed.push(0);
            }else {
                this.arr[i][n] = 1;                   // 1 表示牆
            }
        }
    }
}

 

生成迷宮

 這里需要使用兩個數組,分別保存已訪問和未訪問的頂點。

this.accessed = [];
this.notAccessed = [...];

(1)初始狀態下,notAccessed包含所有頂點,狀態為0表示未訪問,accessed為空。

(2)隨機從notAccessed中抽取一個頂點cur,放入accessed中,cur在notAccessed中的狀態改為1,表示已訪問。

(3)忽略牆,遍歷cur上下左右的頂點。若其中一頂點沒有超出邊界,且未訪問過的,則將頂點加入accessed中,修改notAccessed中的狀態,cur指向該頂點.

(4)循環步驟3,直到accessed.length等於頂點數。generate() {

 let count = this.r * this.c; let cur = MathUtil.randomInt(0, count); let offs = [-this.c, this.c, -1, 1], // 四周頂點在notAccessed的偏移量
offr
= [-1, 1, 0, 0], // 四周頂點在arr的縱向偏移量 offc = [0, 0, -1, 1]; // 四周頂點在arr的橫向偏移量 this.accessed.push(cur); this.notAccessed[cur] = 1; while(this.accessed.length < count) { let tr = Math.floor(cur / this.c), tc = cur % this.c; let num = 0, off = -1;
// 遍歷上下左右頂點
while(++num < 5) { let around = MathUtil.randomInt(0, 4), nr = tr + offr[around], nc = tc + offc[around]; if(nr >= 0 && nc >= 0 && nr < this.r && nc < this.c && this.notAccessed[cur + offs[around]] === 0) { off = around; break; } } // 四周頂點均被訪問,則從已訪問的頂點中隨機抽取一個為cur if(off < 0) { cur = this.accessed[MathUtil.randomInt(0, this.accessed.length)]; }else { tr = 2 * tr + 1; tc = 2 * tc + 1; this.arr[tr + offr[off]][tc + offc[off]] = 0; cur = cur + offs[off]; this.notAccessed[cur] = 1; this.accessed.push(cur); } } }

渲染

最后,利用canvas,根據this.arr中的值,就可以生成迷宮啦。

好像少了入口和出口,直接將this.arr中這兩個位置的值改成0就好了。

迷宮生成之后,可以對指定兩個點生成路徑哦。


免責聲明!

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



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