@@ -3,17 +3,17 @@ import MazeWall from "../Entity/Misc/MazeWall";
33import { VectorAbstract } from "../Physics/Vector" ;
44
55export interface MazeGeneratorConfig {
6- CELL_SIZE : number ,
7- GRID_SIZE : number ,
8- SEED_AMOUNT : number ,
9- TURN_CHANCE : number ,
10- BRANCH_CHANCE : number ,
11- TERMINATION_CHANCE : number
6+ cellSize : number ,
7+ gridSize : number ,
8+ seedAmount : number ,
9+ turnChance : number ,
10+ branchChance : number ,
11+ terminationChance : number
1212}
1313
1414/**
1515 * Implementation details:
16- * Maze map generator by damocles <github.com/SpanksMcYeet >
16+ * Maze map generator by damocles <https:// github.com/lunacles >
1717 * - Added into codebase on Saturday 3rd of December 2022
1818 * - Split into its own file on Wednesday 3rd of December 2025
1919 */
@@ -23,83 +23,83 @@ export default class MazeGenerator {
2323 /** The variables that affect maze generation */
2424 public config : MazeGeneratorConfig ;
2525 /** Stores all the "seed"s */
26- public SEEDS : VectorAbstract [ ] = [ ] ;
26+ public seeds : VectorAbstract [ ] = [ ] ;
2727 /** Stores all the "wall"s, contains cell based coords */
28- public WALLS : ( VectorAbstract & { width : number , height : number } ) [ ] = [ ] ;
28+ public walls : ( VectorAbstract & { width : number , height : number } ) [ ] = [ ] ;
2929 /** Rolled out matrix of the grid */
30- public MAZE : Uint8Array ;
30+ public maze : Uint8Array ;
3131
3232 constructor ( arena : ArenaEntity , config : MazeGeneratorConfig ) {
3333 this . arena = arena ;
3434
3535 this . config = config ;
3636
37- this . MAZE = new Uint8Array ( config . GRID_SIZE * config . GRID_SIZE ) ;
37+ this . maze = new Uint8Array ( config . gridSize * config . gridSize ) ;
3838 }
3939 /** Creates a maze wall from cell coords */
40- public _buildWallFromGridCoord ( gridX : number , gridY : number , gridW : number , gridH : number ) {
41- const scaledW = gridW * this . config . CELL_SIZE ;
42- const scaledH = gridH * this . config . CELL_SIZE ;
43- const scaledX = gridX * this . config . CELL_SIZE - this . arena . width / 2 + ( scaledW / 2 ) ;
44- const scaledY = gridY * this . config . CELL_SIZE - this . arena . height / 2 + ( scaledH / 2 ) ;
40+ public buildWallFromGridCoord ( gridX : number , gridY : number , gridW : number , gridH : number ) {
41+ const scaledW = gridW * this . config . cellSize ;
42+ const scaledH = gridH * this . config . cellSize ;
43+ const scaledX = gridX * this . config . cellSize - this . arena . width / 2 + ( scaledW / 2 ) ;
44+ const scaledY = gridY * this . config . cellSize - this . arena . height / 2 + ( scaledH / 2 ) ;
4545 new MazeWall ( this . arena . game , scaledX , scaledY , scaledH , scaledW ) ;
4646 }
4747 /** Allows for easier (x, y) based getting of maze cells */
48- public _get ( x : number , y : number ) : number {
49- return this . MAZE [ y * this . config . GRID_SIZE + x ] ;
48+ public get ( x : number , y : number ) : number {
49+ return this . maze [ y * this . config . gridSize + x ] ;
5050 }
5151 /** Allows for easier (x, y) based setting of maze cells */
52- public _set ( x : number , y : number , value : number ) : number {
53- return this . MAZE [ y * this . config . GRID_SIZE + x ] = value ;
52+ public set ( x : number , y : number , value : number ) : number {
53+ return this . maze [ y * this . config . gridSize + x ] = value ;
5454 }
5555 /** Converts MAZE grid into an array of set and unset bits for ease of use */
56- public _mapValues ( ) : [ x : number , y : number , value : number ] [ ] {
57- const values : [ x : number , y : number , value : number ] [ ] = Array ( this . MAZE . length ) ;
58- for ( let i = 0 ; i < this . MAZE . length ; ++ i ) values [ i ] = [ i % this . config . GRID_SIZE , Math . floor ( i / this . config . GRID_SIZE ) , this . MAZE [ i ] ] ;
56+ public mapValues ( ) : [ x : number , y : number , value : number ] [ ] {
57+ const values : [ x : number , y : number , value : number ] [ ] = Array ( this . maze . length ) ;
58+ for ( let i = 0 ; i < this . maze . length ; ++ i ) values [ i ] = [ i % this . config . gridSize , Math . floor ( i / this . config . gridSize ) , this . maze [ i ] ] ;
5959 return values ;
6060 }
6161 /** Builds the maze */
6262 public buildMaze ( ) {
6363 // Plant some seeds
6464 for ( let i = 0 ; i < 10000 ; i ++ ) {
6565 // Stop if we exceed our maximum seed amount
66- if ( this . SEEDS . length >= this . config . SEED_AMOUNT ) break ;
66+ if ( this . seeds . length >= this . config . seedAmount ) break ;
6767 // Attempt a seed planting
6868 let seed : VectorAbstract = {
69- x : Math . floor ( ( Math . random ( ) * this . config . GRID_SIZE ) - 1 ) ,
70- y : Math . floor ( ( Math . random ( ) * this . config . GRID_SIZE ) - 1 ) ,
69+ x : Math . floor ( ( Math . random ( ) * this . config . gridSize ) - 1 ) ,
70+ y : Math . floor ( ( Math . random ( ) * this . config . gridSize ) - 1 ) ,
7171 } ;
7272 // Check if our seed is valid (is 3 GU away from another seed, and is not on the border)
73- if ( this . SEEDS . some ( a => ( Math . abs ( seed . x - a . x ) <= 3 && Math . abs ( seed . y - a . y ) <= 3 ) ) ) continue ;
74- if ( seed . x <= 0 || seed . y <= 0 || seed . x >= this . config . GRID_SIZE - 1 || seed . y >= this . config . GRID_SIZE - 1 ) continue ;
73+ if ( this . seeds . some ( a => ( Math . abs ( seed . x - a . x ) <= 3 && Math . abs ( seed . y - a . y ) <= 3 ) ) ) continue ;
74+ if ( seed . x <= 0 || seed . y <= 0 || seed . x >= this . config . gridSize - 1 || seed . y >= this . config . gridSize - 1 ) continue ;
7575 // Push it to the pending seeds and set its grid to a wall cell
76- this . SEEDS . push ( seed ) ;
77- this . _set ( seed . x , seed . y , 1 ) ;
76+ this . seeds . push ( seed ) ;
77+ this . set ( seed . x , seed . y , 1 ) ;
7878 }
7979 const direction : number [ ] [ ] = [
8080 [ - 1 , 0 ] , [ 1 , 0 ] , // left and right
8181 [ 0 , - 1 ] , [ 0 , 1 ] , // up and down
8282 ] ;
8383 // Let it grow!
84- for ( let seed of this . SEEDS ) {
84+ for ( let seed of this . seeds ) {
8585 // Select a direction we want to head in
8686 let dir : number [ ] = direction [ Math . floor ( Math . random ( ) * 4 ) ] ;
8787 let termination = 1 ;
8888 // Now we can start to grow
89- while ( termination >= this . config . TERMINATION_CHANCE ) {
89+ while ( termination >= this . config . terminationChance ) {
9090 // Choose the next termination chance
9191 termination = Math . random ( ) ;
9292 // Get the direction we're going in
9393 let [ x , y ] = dir ;
9494 // Move forward in that direction, and set that grid to a wall cell
9595 seed . x += x ;
9696 seed . y += y ;
97- if ( seed . x <= 0 || seed . y <= 0 || seed . x >= this . config . GRID_SIZE - 1 || seed . y >= this . config . GRID_SIZE - 1 ) break ;
98- this . _set ( seed . x , seed . y , 1 ) ;
97+ if ( seed . x <= 0 || seed . y <= 0 || seed . x >= this . config . gridSize - 1 || seed . y >= this . config . gridSize - 1 ) break ;
98+ this . set ( seed . x , seed . y , 1 ) ;
9999 // Now lets see if we want to branch or turn
100- if ( Math . random ( ) <= this . config . BRANCH_CHANCE ) {
100+ if ( Math . random ( ) <= this . config . branchChance ) {
101101 // If the seeds exceeds 75, then we're going to stop creating branches in order to avoid making a massive maze tumor(s)
102- if ( this . SEEDS . length > 75 ) continue ;
102+ if ( this . seeds . length > 75 ) continue ;
103103 // Get which side we want the branch to be on (left or right if moving up or down, and up and down if moving left or right)
104104 let [ xx , yy ] = direction . filter ( a => a . every ( ( b , c ) => b !== dir [ c ] ) ) [ Math . floor ( Math . random ( ) * 2 ) ] ;
105105 // Create the seed
@@ -108,9 +108,9 @@ export default class MazeGenerator {
108108 y : seed . y + yy ,
109109 } ;
110110 // Push the seed and set its grid to a maze zone
111- this . SEEDS . push ( newSeed ) ;
112- this . _set ( seed . x , seed . y , 1 ) ;
113- } else if ( Math . random ( ) <= this . config . TURN_CHANCE ) {
111+ this . seeds . push ( newSeed ) ;
112+ this . set ( seed . x , seed . y , 1 ) ;
113+ } else if ( Math . random ( ) <= this . config . turnChance ) {
114114 // Get which side we want to turn to (left or right if moving up or down, and up and down if moving left or right)
115115 dir = direction . filter ( a => a . every ( ( b , c ) => b !== dir [ c ] ) ) [ Math . floor ( Math . random ( ) * 2 ) ] ;
116116 }
@@ -120,19 +120,19 @@ export default class MazeGenerator {
120120 for ( let i = 0 ; i < 10 ; i ++ ) {
121121 // Attempt to place it
122122 let seed = {
123- x : Math . floor ( ( Math . random ( ) * this . config . GRID_SIZE ) - 1 ) ,
124- y : Math . floor ( ( Math . random ( ) * this . config . GRID_SIZE ) - 1 ) ,
123+ x : Math . floor ( ( Math . random ( ) * this . config . gridSize ) - 1 ) ,
124+ y : Math . floor ( ( Math . random ( ) * this . config . gridSize ) - 1 ) ,
125125 } ;
126126 // Check if our sprinkle is valid (is 3 GU away from another wall, and is not on the border)
127- if ( this . _mapValues ( ) . some ( ( [ x , y , r ] ) => r === 1 && ( Math . abs ( seed . x - x ) <= 3 && Math . abs ( seed . y - y ) <= 3 ) ) ) continue ;
128- if ( seed . x <= 0 || seed . y <= 0 || seed . x >= this . config . GRID_SIZE - 1 || seed . y >= this . config . GRID_SIZE - 1 ) continue ;
127+ if ( this . mapValues ( ) . some ( ( [ x , y , r ] ) => r === 1 && ( Math . abs ( seed . x - x ) <= 3 && Math . abs ( seed . y - y ) <= 3 ) ) ) continue ;
128+ if ( seed . x <= 0 || seed . y <= 0 || seed . x >= this . config . gridSize - 1 || seed . y >= this . config . gridSize - 1 ) continue ;
129129 // Set its grid to a wall cell
130- this . _set ( seed . x , seed . y , 1 ) ;
130+ this . set ( seed . x , seed . y , 1 ) ;
131131 }
132132 // Now it's time to fill in the inaccessible pockets
133133 // Start at the top left
134134 let queue : number [ ] [ ] = [ [ 0 , 0 ] ] ;
135- this . _set ( 0 , 0 , 2 ) ;
135+ this . set ( 0 , 0 , 2 ) ;
136136 let checkedIndices = new Set ( [ 0 ] ) ;
137137 // Now lets cycle through the whole map
138138 for ( let i = 0 ; i < 3000 && queue . length > 0 ; i ++ ) {
@@ -147,47 +147,47 @@ export default class MazeGenerator {
147147 [ x , y + 1 ] , // bottom
148148 ] ) {
149149 // If its a wall ignore it
150- if ( this . _get ( nx , ny ) !== 0 ) continue ;
151- let i = ny * this . config . GRID_SIZE + nx ;
150+ if ( this . get ( nx , ny ) !== 0 ) continue ;
151+ let i = ny * this . config . gridSize + nx ;
152152 // Check if we've already checked this cell
153153 if ( checkedIndices . has ( i ) ) continue ;
154154 // Add it to the checked cells if we haven't already
155155 checkedIndices . add ( i ) ;
156156 // Add it to the next cycle to check
157157 queue . push ( [ nx , ny ] ) ;
158158 // Set its grid to an accessible cell
159- this . _set ( nx , ny , 2 ) ;
159+ this . set ( nx , ny , 2 ) ;
160160 }
161161 }
162162 // Cycle through all areas of the map
163- for ( let x = 0 ; x < this . config . GRID_SIZE ; x ++ ) {
164- for ( let y = 0 ; y < this . config . GRID_SIZE ; y ++ ) {
163+ for ( let x = 0 ; x < this . config . gridSize ; x ++ ) {
164+ for ( let y = 0 ; y < this . config . gridSize ; y ++ ) {
165165 // If we're not a wall, ignore the cell and move on
166- if ( this . _get ( x , y ) === 2 ) continue ;
166+ if ( this . get ( x , y ) === 2 ) continue ;
167167 // Define our properties
168168 let chunk = { x, y, width : 0 , height : 1 } ;
169169 // Loop through adjacent cells and see how long we should be
170- while ( this . _get ( x + chunk . width , y ) !== 2 ) {
171- this . _set ( x + chunk . width , y , 2 ) ;
170+ while ( this . get ( x + chunk . width , y ) !== 2 ) {
171+ this . set ( x + chunk . width , y , 2 ) ;
172172 chunk . width ++ ;
173173 }
174174 // Now lets see if we need to be t h i c c
175175 outer: while ( true ) {
176176 // Check the row below to see if we can still make a box
177177 for ( let i = 0 ; i < chunk . width ; i ++ )
178178 // Stop if we can't
179- if ( this . _get ( x + i , y + chunk . height ) === 2 ) break outer;
179+ if ( this . get ( x + i , y + chunk . height ) === 2 ) break outer;
180180 // If we can, remove the line of cells from the map and increase the height of the block
181181 for ( let i = 0 ; i < chunk . width ; i ++ )
182- this . _set ( x + i , y + chunk . height , 2 ) ;
182+ this . set ( x + i , y + chunk . height , 2 ) ;
183183 chunk . height ++ ;
184184 }
185- this . WALLS . push ( chunk ) ;
185+ this . walls . push ( chunk ) ;
186186 }
187187 }
188188 // Create the walls!
189- for ( let { x, y, width, height} of this . WALLS ) {
190- this . _buildWallFromGridCoord ( x , y , width , height ) ;
189+ for ( let { x, y, width, height} of this . walls ) {
190+ this . buildWallFromGridCoord ( x , y , width , height ) ;
191191 }
192192 }
193193
@@ -196,11 +196,11 @@ export default class MazeGenerator {
196196 const width = this . arena . width / 2 ;
197197 const height = this . arena . height / 2 ;
198198
199- for ( const wall of this . WALLS ) {
200- const wallX = wall . x * this . config . CELL_SIZE - width ;
201- const wallY = wall . y * this . config . CELL_SIZE - height ;
202- const wallW = wall . width * this . config . CELL_SIZE ;
203- const wallH = wall . height * this . config . CELL_SIZE ;
199+ for ( const wall of this . walls ) {
200+ const wallX = wall . x * this . config . cellSize - width ;
201+ const wallY = wall . y * this . config . cellSize - height ;
202+ const wallW = wall . width * this . config . cellSize ;
203+ const wallH = wall . height * this . config . cellSize ;
204204 if (
205205 x >= wallX &&
206206 x <= wallX + wallW &&
@@ -212,4 +212,4 @@ export default class MazeGenerator {
212212 }
213213 return false ;
214214 }
215- }
215+ }
0 commit comments