1
- using System ;
1
+ using System ;
2
2
using System . Collections . Generic ;
3
3
4
4
class Maze {
5
5
6
- private static Cell [ ] [ ] maze ;
6
+ private const string WallWithLeftSideEmpty = "= " ;
7
+ private const string WallWithLeftSideFull = "| " ;
8
+ private const string FloorWithHole = "+ " ;
9
+ private const string FloorWithoutHole = "+---" ;
10
+ private const string WallEnd = "|\n " ;
11
+ private const string WallEndWithExit = "=\n " ;
12
+ private const string FloorCorner = "+\n " ;
13
+ private static Cell [ ] [ ] _maze ;
7
14
8
15
static void Main ( string [ ] args ) {
9
16
Console . ForegroundColor = ConsoleColor . Green ;
@@ -61,13 +68,110 @@ private static void GenerateMaze(bool showAnimation) {
61
68
Console . WriteLine ( "Generating maze " + width + "x" + height ) ;
62
69
GenerateEmptyMaze ( width , height ) ;
63
70
64
- // TODO Algorithm
71
+ MazeGeneratingAlgorithm ( ) ;
72
+
65
73
PrintMaze ( ) ;
66
74
Console . ReadKey ( ) ;
67
75
}
68
76
69
- private static void PrintMaze ( ) {
77
+ private static void MazeGeneratingAlgorithm ( ) {
78
+ // Starting point at (0, 0)
79
+ _maze [ 0 ] [ 0 ] . Left = true ;
80
+ var cursor = ( 0 , 0 ) ;
81
+ var logStack = new Stack < ( int , int ) > ( ) ;
82
+ // Depth-first search algorithm
83
+
84
+ do {
85
+ _maze [ cursor . Item1 ] [ cursor . Item2 ] . Visited = true ;
86
+ logStack . Push ( cursor ) ;
87
+
88
+ if ( IsDeadEnd ( cursor ) ) {
89
+ logStack . Pop ( ) ;
90
+ if ( logStack . Count == 0 ) break ;
91
+ }
92
+
93
+
94
+
95
+ } while ( cursor . Equals ( ( 0 , 0 ) ) ) ;
96
+
97
+
98
+ // Exit at bottom right corner
99
+ _maze [ _maze . Length - 1 ] [ _maze [ 0 ] . Length - 1 ] . Right = true ;
100
+ }
70
101
102
+ private static bool IsDeadEnd ( ( int , int ) cursor ) {
103
+
104
+ // Cell that has no unvisited neighbors being considered a dead-end ~ Wikipedia
105
+
106
+ // cursor.Item1 - Row (Y)
107
+ // cursor.Item2 - Column (X)
108
+
109
+ // Top
110
+ if ( IsTopCellNotVisited ( cursor ) ) {
111
+ return false ;
112
+ }
113
+
114
+ // Bottom
115
+ if ( IsBottomCellNotVisited ( cursor ) ) {
116
+ return false ;
117
+ }
118
+
119
+ // Left
120
+ if ( IsLeftCellNotVisisted ( cursor ) ) {
121
+ return false ;
122
+ }
123
+
124
+ // Right
125
+ if ( IsRightCellNotVisited ( cursor ) ) {
126
+ return false ;
127
+ }
128
+
129
+ return true ;
130
+ }
131
+
132
+ private static bool IsRightCellNotVisited ( ( int , int ) cursor ) {
133
+ return IsCellOnRight ( cursor ) && ! _maze [ cursor . Item1 ] [ cursor . Item2 + 1 ] . Visited ;
134
+ }
135
+
136
+ private static bool IsLeftCellNotVisisted ( ( int , int ) cursor ) {
137
+ return IsCellOnLeft ( cursor ) && ! _maze [ cursor . Item1 ] [ cursor . Item2 - 1 ] . Visited ;
138
+ }
139
+
140
+ private static bool IsBottomCellNotVisited ( ( int , int ) cursor ) {
141
+ return IsCellBelowCursor ( cursor ) && ! _maze [ cursor . Item1 + 1 ] [ cursor . Item2 ] . Visited ;
142
+ }
143
+
144
+ private static bool IsTopCellNotVisited ( ( int , int ) cursor ) {
145
+ return IsCellAboveCursor ( cursor ) && ! _maze [ cursor . Item1 - 1 ] [ cursor . Item2 ] . Visited ;
146
+ }
147
+
148
+ private static bool IsCellOnRight ( ( int , int ) cursor ) {
149
+ return cursor . Item2 + 1 <= _maze [ 0 ] . Length ;
150
+ }
151
+
152
+ private static bool IsCellOnLeft ( ( int , int ) cursor ) {
153
+ return cursor . Item2 - 1 > 0 ;
154
+ }
155
+
156
+ private static bool IsCellBelowCursor ( ( int , int ) cursor ) {
157
+ return cursor . Item1 + 1 <= _maze . Length ;
158
+ }
159
+
160
+ private static bool IsCellAboveCursor ( ( int , int ) cursor ) {
161
+ return cursor . Item1 - 1 > 0 ;
162
+ }
163
+
164
+ private static bool CursorIsCorrect ( ( int , int ) cursor ) {
165
+ return cursor . Item1 - 1 >= 0 &&
166
+ cursor . Item2 - 1 >= 0 &&
167
+ cursor . Item1 + 1 < _maze . Length &&
168
+ cursor . Item2 + 1 < _maze [ 0 ] . Length ;
169
+ }
170
+
171
+ private static void PrintMaze ( ) {
172
+ Console . Clear ( ) ;
173
+ PrintTitle ( ) ;
174
+
71
175
//+---+
72
176
//| | 1x1 block
73
177
//+---+
@@ -77,43 +181,47 @@ private static void PrintMaze() {
77
181
board = AddOneLine ( board ) ;
78
182
79
183
// Add all maze
80
- for ( var row = 0 ; row < maze . Length ; row ++ ) {
184
+ for ( var row = 0 ; row < _maze . Length ; row ++ ) {
81
185
for ( var k = 1 ; k <= 2 ; k ++ ) {
82
- for ( var column = 0 ; column < maze [ row ] . Length ; column ++ ) {
186
+ for ( var column = 0 ; column < _maze [ row ] . Length ; column ++ ) {
83
187
if ( ShouldPrintVertical ( k ) ) {
84
188
if ( ShouldPrintWall ( row , column ) )
85
- board += "| " ;
189
+ board += WallWithLeftSideFull ;
86
190
else {
87
- board += "; " ;
191
+ board += WallWithLeftSideEmpty ;
88
192
}
89
193
} else {
90
194
if ( ShouldPrintFloor ( row , column ) )
91
- board += "+---" ;
195
+ board += FloorWithoutHole ;
92
196
else {
93
- board += "+-_-" ;
197
+ board += FloorWithHole ;
94
198
}
95
199
}
96
200
}
97
- board = AddEndLines ( board , k ) ;
201
+ board = AddEndLines ( board , k , row ) ;
98
202
}
99
203
}
100
204
// Print maze
101
205
Console . WriteLine ( board ) ;
102
206
}
103
207
104
208
private static bool ShouldPrintFloor ( int row , int column ) {
105
- return maze [ row ] [ column ] . Bottom == false ;
209
+ return _maze [ row ] [ column ] . Bottom == false ;
106
210
}
107
211
108
212
private static bool ShouldPrintWall ( int row , int column ) {
109
- return maze [ row ] [ column ] . Left == false ;
213
+ return _maze [ row ] [ column ] . Left == false ;
110
214
}
111
215
112
- private static string AddEndLines ( string board , int k ) {
216
+ private static string AddEndLines ( string board , int k , int row ) {
113
217
if ( ShouldPrintVertical ( k ) ) {
114
- board += "|\n " ;
218
+ if ( _maze [ row ] [ _maze . Length - 1 ] . Right ) {
219
+ board += WallEndWithExit ;
220
+ } else {
221
+ board += WallEnd ;
222
+ }
115
223
} else {
116
- board += "+ \n " ;
224
+ board += FloorCorner ;
117
225
}
118
226
119
227
return board ;
@@ -124,7 +232,7 @@ private static bool ShouldPrintVertical(int k) {
124
232
}
125
233
126
234
private static string AddOneLine ( string board ) {
127
- for ( var j = 0 ; j < maze [ 0 ] . Length ; j ++ ) {
235
+ for ( var j = 0 ; j < _maze [ 0 ] . Length ; j ++ ) {
128
236
board += "+---" ;
129
237
}
130
238
@@ -133,19 +241,19 @@ private static string AddOneLine(string board) {
133
241
}
134
242
135
243
private static void GenerateEmptyMaze ( int width , int height ) {
136
- maze = new Cell [ height ] [ ] ;
244
+ _maze = new Cell [ height ] [ ] ;
137
245
for ( var row = 0 ; row < height ; row ++ ) {
138
- maze [ row ] = new Cell [ width ] ;
139
- for ( var column = 0 ; column < maze [ row ] . Length ; column ++ ) {
140
- maze [ row ] [ column ] = new Cell ( ) ;
246
+ _maze [ row ] = new Cell [ width ] ;
247
+ for ( var column = 0 ; column < _maze [ row ] . Length ; column ++ ) {
248
+ _maze [ row ] [ column ] = new Cell ( ) ;
141
249
}
142
250
}
143
251
}
144
252
145
253
private static int GetWidthFromPlayer ( ) {
146
254
int width ;
147
255
Console . Write ( "\b Enter width: " ) ;
148
- while ( ! int . TryParse ( Console . ReadLine ( ) , out width ) || width <= 0 || width > 100 ) {
256
+ while ( ! int . TryParse ( Console . ReadLine ( ) , out width ) || width < 2 || width > 100 ) {
149
257
Console . WriteLine ( "Wrong value" ) ;
150
258
Console . Write ( "\b Enter width: " ) ;
151
259
}
@@ -156,7 +264,7 @@ private static int GetWidthFromPlayer() {
156
264
private static int GetHeightFromPlayer ( ) {
157
265
int height ;
158
266
Console . Write ( "\b Enter height: " ) ;
159
- while ( ! int . TryParse ( Console . ReadLine ( ) , out height ) || height <= 0 || height > 100 ) {
267
+ while ( ! int . TryParse ( Console . ReadLine ( ) , out height ) || height < 2 || height > 100 ) {
160
268
Console . WriteLine ( "Wrong value" ) ;
161
269
Console . Write ( "\b Enter height: " ) ;
162
270
}
@@ -180,5 +288,5 @@ class Cell {
180
288
public bool Bottom ;
181
289
public bool Left ;
182
290
public bool Right ;
183
- public bool visited ;
291
+ public bool Visited ;
184
292
}
0 commit comments