Programmer / Web Developer
San Antonio, TX
January 1996
Derp Derp Code
For Love of Pinball
Learn Unity/C#
Awesome Thoery Idle
Many years ago, 2008 if my guess is right, I had the idea to write a random dungeon generator. I succeeded but left it somewhat unfinished. I picked that little project back up in mid/late 2018 as part of my Awesome Theory 2.0 project. I am going to deconstruct it piece by piece in order to better understand what the heck I did 10+ years ago. I won't lie, some of the code is brilliant in my opinion, but some of my past decisions are hard to understand. Note that this is one way to accomplish this - there are probably many other better ways. This is just what I came up with to solve the problem.
First things first, the actual construction of a dungeon should be a function, and so the first thing to think about it what parameters you need.
function build_dungeon($level, $floors = 1, $max_x = 0, $max_y = 0) {
Level is the difficulty of the dungeon, which determines how hard the monsters inside it will be. Then we need to know how many floors it will have, and the maximum size of the square that will contain the dungeon. It is possible in the future I might want additional parameters, but these seem like the basic mandatory few.$sql = "INSERT INTO dungeon SET owner='$user_id', type='dungeon', level=$level, floors=$floors, cur_floor=1, status=1";
if (@mysqli_query($con, $sql)) {
$d_id = mysqli_insert_id($con);
The first thing I do is create a DB record of the dungeon based on the parameters provided. Because the table holds dungeons for all users, I need to specify the owner. I am also using a current floor column to determine which floor of the dungeon the user is on at the moment, which I'll use later to determine which floor to load and display. The status field is used to determine which dungeon the user is currently in. Then I grab the unique ID of the dungeon which will be very important for building the floors later.$i = 1;
while ($i <= $floors) {
if (!$max_x) {
$max_x = rand(8,17);
}
if (!$max_y) {
$max_y = rand(7,11);
}
$min_cells = round(($max_x + 1) * ($max_y + 1) * .70);
$start = array(0,0);
$map = array(array(), array());
Now I'm looping through the floors, building each one. First, if the maximum size of the dungeon wasn't specified when the function was called, I determine it here randomly. The min_cells variable is used to ensure that at least a certain percentage of the square area of the dungeon is filled with actual dungeon cells. In this case, I am saying that at least 70% of the specified cells (for example, 70 cells out of a 10 by 10 dungeon) must be filled with dungeon tiles and not be 'blanks.' This could easily (and probably should be) a parameter that could be passed to the function, setting it at 70% if it is not passed. That would make a lot of sense. I also initialize the starting spot on the map and the map itself.$rand = rand(0,3);
$facing = 0;
if ($rand == 0) {
$start[1] = rand(0, $max_y);
$start[0] = 0;
$facing = $e;
} else if ($rand == 1) {
$start[1] = rand(0, $max_y);
$start[0] = $max_x;
$facing = $w;
} else if ($rand == 2) {
$start[1] = 0;
$start[0] = rand(0, $max_x);
$facing = $s;
} else {
$start[1] = $max_y;
$start[0] = rand(0, $max_x);
$facing = $n;
}
$map[$start[0]][$start[1]] = $facing;
$cur_x = $start[0];
$cur_y = $start[1];
global $total_cells;
$total_cells = 1;
First a note: $e, $w, $s, and $n are globals that I assign the values 1, 2, 4, and 8, respectively. Each square of the dungeon gets a number value from 0 to 15 that determines which directions are open from the square and which ones are walls. For example, if the square value is 12, I know that from it you could go north and south.
Known Bugs
Tags list: top margin errors when only one item on a line