BuckraMega

Avatar


Programmer / Web Developer

Newport News, VA

January 1996


Learn Unity/C#

Awesome Thoery Idle



Note!

This site is under construction. Don't mind the mess - maybe someday this will be worth reading!

Welcome to Derp...Derp...Code!, my programming journal/blog. This site is more for me than anyone else, but if you are here and reading, that's great! You might wonder about the name - I might be good at programming, but I am a bad programmer, so I tend to derp a lot before producing worthwhile code.

Avatar5 Jan 2019

Coding a random dungeon generator, pt 1


An exercise in sloppy spaghetti coding

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.

Here I randomly determine which way the user will be facing when entering the dungeon and set the starting spot randomly along the wall opposite the faced direction. Then that line with the map array sets the square that contains the starting spot (also the dungeon exit) as a square from which you can only travel away from the outer edge. Finally, I set the cur_x and cur_y values to the start value, since the player will currently be at the start o the dungeon when it is created. Since I manually created the starting cell here, I initialize total_cells and give it a value of 1. I make it global because I will use it and increment in later functions, though I probably could have passed it in and out of functions instead, but I was really bad at that type of stuff when I wrote this and only marginally better now. And don't get me started on objects, I know, I know!

That is it for part 1. After this, I'll go into functions that actually start building the map and that is where it gets really interesting.

Tags: Awesome Theory code dungeon generator random

Enter a comment

Name:
Comment (max 5K characters):

User comments

Current Working Links:

Acrophobia

Awesome Theory Demo





Known Bugs

Tags list: top margin errors when only one item on a line