最近經常在機房看同學在玩一個走迷宮的游戲,比較有趣,自己也用java寫一個實現隨機生成迷宮的算法,其實就是一個圖的深度優先遍歷算法.基本思想就是,迷宮中的每個點都有四面墻,然后呢。
1、從任意一點開始訪問(我的算法中固定是從(0,0)點開始),往四個方向中的隨機一個訪問(每訪問到一個可訪問的點,就去掉該點的那個方向的墻),被訪問點繼續以這種方識向下進行訪問。
2、對每個被訪問的點都被標識為已訪問,當一個點對某個方向進行訪問時我們首先會判斷被訪問點是否已被訪問,或者觸到邊界.如果該點四個方向皆已訪問或已無法訪問,就退回上一個點。上一個點繼續這個過程。
這樣一次遍歷下來,可以確定每個點都被訪問過,而且由于每次訪問的方向都是隨機,這就會形成許多不同遍歷情況,同時每兩個點之間的路徑是唯一,也就形成不同的迷宮,且是起點到終點只有唯一路徑,這是由于圖的深度遍歷算法的特點所決定的。算法的實現上,主要是利用棧,第一次,先把第一個點壓進棧里,每訪問到一個點,就把該點壓進棧里,我們再對棧頂的點進行四個方向的隨機訪問,訪問到新點,又把新點壓進去,一旦這個點四個方向都無法訪問了,就讓該點退棧,再對棧頂的點的四個方向進行訪問,以此類推,直到棧里的點都全部退出了,我們的遍歷就成功了,這是一個遞歸的過程,這個算法自然可以用遞歸的方法來實現,不過這里我這樣做,而是手工用一個數組作為棧來實現,呵呵~~說了這么多,也不知道自己要表達的有沒表達出來。不過我感覺我的具體代碼設計還是寫的不好,還有很多地方缺乏完善和優化,權當是算法練習,以下是兩個關鍵類的核心代碼,至于表示層的代碼就不貼出來了,因為那些都很瑣碎。
下面是效果圖:
迷宮的類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
//作者:zhongzw //郵箱:zhong317@126.com package cn.zhongzw.model; import java.util.arraylist; import java.util.random; public class mazemodel { private int width = 0 ; private int height = 0 ; private random rnd = new random(); public mazemodel() { this .width = 50 ; //迷宮寬度 this .height = 50 ; //迷宮高度 } public int getwidth() { return width; } public void setwidth( int width) { this .width = width; } public int getheight() { return height; } public void setheight( int height) { this .height = height; } public mazemodel( int width, int height) { super (); this .width = width; this .height = height; } public arraylist < mazepoint > getmaze() { arraylist < mazepoint > maze = new arraylist < mazepoint > (); for ( int h = 0 ; h < height; h++) { for ( int w = 0 ; w < width; w++) { mazepoint point = new mazepoint(w, h); maze.add(point); } } return createmaze(maze); } private arraylist < mazepoint > createmaze(arraylist < mazepoint > maze) { int top = 0 ; int x = 0 ; int y = 0 ; arraylist < mazepoint > team = new arraylist < mazepoint > (); team.add(maze.get(x + y * width)); while (top >= 0 ) { int [] val = new int [] { - 1 , - 1 , - 1 , - 1 }; int times = 0 ; boolean flag = false ; mazepoint pt = (mazepoint) team.get(top); x = pt.getx(); y = pt.gety(); pt.visted = true ; ro1: while (times < 4 ) { int dir = rnd.nextint( 4 ); if (val[dir] == dir) continue ; else val[dir] = dir; switch (dir) { case 0 : // 左邊 if ((x - 1 ) >= 0 && maze.get(x - 1 + y * width).visted == false ) { maze.get(x + y * width).setleft(); maze.get(x - 1 + y * width).setright(); team.add(maze.get(x - 1 + y * width)); top++; flag = true ; break ro1; } break ; case 1 : // 右邊 if ((x + 1 ) < width && maze.get(x + 1 + y * width).visted == false ) { maze.get(x + y * width).setright(); maze.get(x + 1 + y * width).setleft(); team.add(maze.get(x + 1 + y * width)); top++; flag = true ; break ro1; } break ; case 2 : // 上邊 if ((y - 1 ) >= 0 && maze.get(x + (y - 1 ) * width).visted == false ) { maze.get(x + y * width).setup(); maze.get(x + (y - 1 ) * width).setdown(); team.add(maze.get(x + (y - 1 ) * width)); top++; flag = true ; break ro1; } break ; case 3 : // 下邊 if ((y + 1 ) < height && maze.get(x + (y + 1 ) * width).visted == false ) { maze.get(x + y * width).setdown(); maze.get(x + (y + 1 ) * width).setup(); team.add(maze.get(x + (y + 1 ) * width)); top++; flag = true ; break ro1; } break ; } times += 1 ; } if (!flag) { team.remove(top); top -= 1 ; } } return maze; } } |
迷宮
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
//作者:zhongzw //郵箱:zhong317@126.com package cn.zhongzw.model; import java.util.*; import java.lang.*; public class mazepoint { private int left = 0 ; private int right = 0 ; private int up = 0 ; private int down = 0 ; private int x; private int y; public boolean visted; public mazepoint( int x, int y) { this .x = x; this .y = y; } public int getleft() { return left; } public void setleft() { this .left = 1 ; } public int getright() { return right; } public void setright() { this .right = 1 ; } public int getup() { return up; } public void setup() { this .up = 1 ; } public int getdown() { return down; } public void setdown() { this .down = 1 ; } public int getx() { return x; } public void setx( int x) { this .x = x; } public int gety() { return y; } public void sety( int y) { this .y = y; } } |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://blog.csdn.net/woshizoe/article/details/27345201