Open CromulentEntity opened 2 years ago
My original plan for this was to make use of a Maze Generation Algorithm in order to generate a random map. After giving it some more thought, this clashes with the current design philosophy of the Map object.
Currently, the map is a 2d array. Each point in the array, which I call a tile, is either a Room or a Rock. Rooms allow traversal to and from any other adjacent room, as long as both are unlocked. Rocks completely block player movement.
The Maze Generation Algorithms seem to make more sense as follows. Every single tile is a Room. Each Room has 4 Doors or Walls. For the entire map, all walls start in-tact/doors start locked. As the algorithm carves out paths, we mark walls as demolished or doors as unlocked. In doing this, each room will end up with a random combination of ways the player can enter and leave.
If we were to try and place Rocks between the rooms where the algorithm has deemed there to be walls/locked doors, we would end up with a maze that is bigger than the dimensions supplied by the user. That's not acceptable.
I built a map/maze generator years ago through trial and error, without researching an algorithm to base it on. From what I remember, that algorithm would not fill the entire X*Y grid with rooms. There would be many empty "tiles" that were functionally the same as the "Rocks" I have defined now. It may also have given each room 4 doors, and unlocked those along the paths generated by the algorithm. Kind of a hybrid between the currently implemented approach in this game, and the approach which I theorized in the above comment to be the proper way to implement maze generation in a tile system.
My intent is to dig out the old algorithm, pick apart how it worked, and then decide how I would like to proceed here. That may be redesigning the tile system in the game, or it may be finding a different sort of algorithm to adopt to the current tile system.
For future reference, good articles on Maze Generation algorithms:
Very large generation example from old map generator.
This old generator worked as follows:
It would then take the following optional steps:
Implementation Notes:
An important note about this implementation. For whatever reason, there are 3 separate "copies" of the map involved in this process. There is the 2D String array, mentioned in step one. There is the Linked List of int[] x,y pairs from step two. And finally, there is a 2D array of Room objects from step 7. Why it is this way I cannot fathom.
The 2D String Array is updated whenever a new room is created, and is used to check if a potential new room has too many neighbors. If more than one of the cells immediately above or to the side of the queried cell is set to a character that represents a room, the new room is not created.
The int[] Linked List is used to establish easy back and forth movement along the path when creating new rooms and removing those that result in dead ends.
The 2D Room array is actually used by the game for most functions outside of printing the map, for which it uses the String array representation instead. Movement is based entirely on what doors each room contains from the generation process. These doors reference other Room objects. The int[] linked list is effectively discarded after the map is generated.
Side paths are generated the same way the main one is, although the implementation looks bugged.
Improvements: If I were to implement something similar to this, the 3 map representations could be squished down to 1. A 2D array of rooms, each containing a "String icon" field which can be accessed to get the textual representation of that room. Each room would then reference the next and previous Room objects in the main path, as well as any offshoot paths that are added after the fact. I guess this would make each room double as a node in a linked list kind of? Need a little more thought for that part.
There are also parts of the code that are very much important for the map generation which actually take place inside of the Room objects instead. This functionality should be lifted into the Map class.
Looking at that old generator was pretty neat. I'll need some time to digest the pros and cons of going in that direction versus using/tweaking an established maze generation algorithm. Will come back to this.
Currently the map is static. The intention is to have it generate a random layout each time.