Skip to main content
Code Review

Return to Revisions

2 of 3
Added usage example

Basic Dungeon Generator in C#

After much thought, I decided to make my own dungeon generator, after reading a bit about it, and becoming interested in the subject, this is my first effort about it. I can only say that it works, but I believe there's room for some improvement, because I believe my self-taught coding skills are basic.

So, mustering some courage,here is my work (be as incisive as you need to be):

Tile.cs

using System;
using System.Collections.Generic;
using System.Text;
namespace DungeonGenerator
{
 struct Cell
 {
 /// <summary>
 /// Location in the grid
 /// </summary>
 public CellType CellType;
 public Cell(CellType cellType)
 {
 CellType = cellType;
 }
 public override string ToString()
 {
 return "Type: " + CellType;
 }
 }
}

CellType.cs

 /// <summary>
 /// If the cell is walkable or not
 /// </summary>
 public enum CellType
 {
 WALL, GROUND, START
 }

Direction.cs

enum Direction
{
 UP, DOWN, LEFT, RIGHT
}

DungeonGenerator.cs

 using System;
 namespace DungeonGenerator
 {
 public class DungeonGenerator
 {
 public int Width { get; set; }
 public int Height { get; set; }
 public int CellsToGenerate { get; set; }
 Cell[,] DungeonCells { get; set; }
 public void CreateDungeonRoom(int RoomWidth, int RoomHeight)
 {
 Width = RoomWidth;
 Height = RoomHeight;
 DungeonCells = new Cell[Width,Height];
 for (int y = 0; y < Height; y++)
 {
 for (int x = 0; x < Width; x++)
 {
 CellType cellType = CellType.WALL;
 DungeonCells[x, y] = new Cell(cellType);
 }
 }
 }
 /// <summary>
 /// Populate the insides of the room
 /// </summary>
 public void CreateDungeonScenery()
 {
 //Make it so that the outside walls are untouched
 int minValueXY = 1;
 int maxValueX = Width - 2;
 int maxValueY = Height - 2;
 //Choose a random position in the room
 Random random = new Random();
 int startX = random.Next(minValueXY, maxValueX);
 int startY = random.Next(minValueXY, maxValueY);
 //Mark it as the starting position, for player placement, maybe?
 DungeonCells[startX, startY] = new Cell(CellType.START);
 //Get directions to an array for random choosing
 Array values = Enum.GetValues(typeof(Direction));
 //From the starting position, proceed to create X number of ground cells
 int cellCount = 0;
 while (cellCount < CellsToGenerate)
 {
 //Choose a direction at random
 Direction direction = (Direction)values.GetValue(random.Next(values.Length));
 if (direction == Direction.UP)
 {
 startY -= 1;
 if (startY < minValueXY) { startY = minValueXY; }
 }
 else if (direction == Direction.DOWN)
 {
 if (startY < maxValueY) { startY += 1; }
 }
 else if (direction == Direction.LEFT)
 {
 startX -= 1;
 if (startX < minValueXY) { startX = minValueXY; }
 }
 else if (direction == Direction.RIGHT)
 {
 
 if (startX < maxValueX) { startX += 1; }
 }
 //From the position chosen, mark it as ground, if possible
 if (CreateGround(startX, startY))
 {
 //Mark the cell as ground
 DungeonCells[startX, startY].CellType = CellType.GROUND;
 //Add one to cells created
 cellCount++;
 }
 }
 }
 private bool CreateGround(int startX, int startY)
 {
 //There's not a wall there, so there's nothing to be done here
 if (DungeonCells[startX, startY].CellType != CellType.WALL)
 {
 return false;
 }
 
 return true;
 }
 public void LogDungeon()
 {
 Console.Clear();
 for (int y = 0; y < Height; y++)
 {
 string line = "";
 for (int x = 0; x < Width; x++)
 {
 if (DungeonCells[x, y].CellType == CellType.GROUND)
 {
 line += "O";
 }
 else if (DungeonCells[x, y].CellType == CellType.WALL)
 {
 line += "█";
 }
 else if (DungeonCells[x, y].CellType == CellType.START)
 {
 line += "H";
 }
 }
 Console.WriteLine(line);
 }
 }
 }
 }

From the start, I realize I can improve the code:

By preventing backtracking, but backtracking sometimes makes some nice crevices here and there. Resolve this by making impossible to select the direct opposite of the previous direction? I want to figure out a way to improve that direction choosing part (currently I don't know how).

Here is an example of a dungeon with 115 width, 32 height and 1500 ground tiles and the player starting position (it's the H somewhere) [![enter image description here][1]][1] [1]: https://i.sstatic.net/32UVM.png

Thanks to whoever spends a bit of time helping me out.

EDIT As requested, to use, just add the classes to your project, and call the builder like so:

 dungeonGenerator = new DungeonGenerator();
 dungeonGenerator.CreateDungeonRoom(115, 32);
 dungeonGenerator.CellsToGenerate = 1500;
 dungeonGenerator.CreateDungeonScenery();
 dungeonGenerator.LogDungeon();

On purpose, I left the number of cells to generate out of the CreateDungeonRoom() method because I'm still deciding if I really want to make users insert the number of ground tiles as a specific number or a percentage, or enum. We will see.

lang-cs

AltStyle によって変換されたページ (->オリジナル) /