Skip to content

Instantly share code, notes, and snippets.

@mgeist
Created August 3, 2012 05:19
Show Gist options
  • Save mgeist/3244617 to your computer and use it in GitHub Desktop.
Save mgeist/3244617 to your computer and use it in GitHub Desktop.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class DungeonGenerator : MonoBehaviour {
// Cleanup, organize.
int height = 40;
int width = 40;
bool[,] currentGrid;
Vector2[] neighborOffsets = new[]
{
new Vector2(-1, -1),
new Vector2(-1, 0),
new Vector2(-1, 1),
new Vector2(0, -1),
new Vector2(0, 1),
new Vector2(1, -1),
new Vector2(1, 0),
new Vector2(1, 1)
};
List<GameObject> liveCells = new List<GameObject>();
int genAmount = 3;
int generations = 0;
float startTime;
float nextGo;
float cooldown = 0.2f;
float chanceToBeWall = 0.41f;
// Use this for initialization
void Start () {
MakeWorkableMap();
}
// Update is called once per frame
void Update () {
}
void MakeWorkableMap() {
currentGrid = new bool[width, height];
int size;
GenerateMap();
RenderCurrentGen();
size = DetermineSize();
if (size < 600) {
MakeWorkableMap();
}
}
void GenerateMap() {
RandomPointGeneration();
while (generations <= genAmount) {
currentGrid = CalculateNextGen();
generations++;
}
}
void RandomPointGeneration() {
for (int y = 0; y < currentGrid.GetLength(1); y++) {
for (int x = 0; x < currentGrid.GetLength(0); x++) {
// This seems like it might be less efficient
if (!FillIfBorder(currentGrid, x, y) && Random.value < chanceToBeWall) {
currentGrid[x, y] = true;
}
}
}
}
bool FillIfBorder(bool[,] map, int x, int y) {
if (x == 0
|| y == 0
|| x == currentGrid.GetLength(0) - 1
|| y == currentGrid.GetLength(1) - 1) {
map[x, y] = true;
return true;
}
else {
return false;
}
}
// Rename into more general function
// Supply the array to function, color of cubes, list (if any) to clear/replace.
// Return list of gameobjects
//
// or keep as is. Leaning towards this currently.
void RenderCurrentGen() {
foreach (GameObject box in liveCells) {
Destroy(box);
}
liveCells.Clear();
for (int y = 0; y < currentGrid.GetLength(1); y++) {
for (int x = 0; x < currentGrid.GetLength(0); x++) {
if (currentGrid[x, y] == true) {
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.position = new Vector3(x, y, 0);
liveCells.Add(cube);
}
}
}
}
// Provide current generation?
bool[,] CalculateNextGen() {
bool[,] newGrid = new bool[width, height];
int neighborCount = 0;
for (int y = 0; y < currentGrid.GetLength(1); y++) {
for (int x = 0; x < currentGrid.GetLength(0); x++) {
neighborCount = CalculateNeighborAmount(x, y);
if (!FillIfBorder(newGrid, x, y)) {
if (neighborCount >= 4 && currentGrid[x, y] == true) {
newGrid[x, y] = true;
}
else if (neighborCount >= 5 && currentGrid[x, y] == false) {
newGrid[x, y] = true;
}
else {
newGrid[x, y] = false;
}
}
}
}
return newGrid;
}
int CalculateNeighborAmount(int x, int y) {
int neighbors = 0;
foreach (Vector2 offset in neighborOffsets) {
Vector2 neighborLoc = new Vector2(x + offset.x, y + offset.y);
if (IsValidPoint(neighborLoc) && currentGrid[(int)neighborLoc.x, (int)neighborLoc.y]) {
neighbors++;
}
}
return neighbors;
}
bool IsValidPoint(Vector2 loc) {
return loc.x >= 0 && loc.y >= 0 && loc.x < currentGrid.GetLength(0) && loc.y < currentGrid.GetLength(1);
}
Vector2 FindFirstOpenCell(bool[,] map) {
for (int y = 0; y < map.GetLength(1); y++) {
for (int x = 0; x < map.GetLength(0); x++) {
if (map[x, y] == false) {
return new Vector2(x, y);
}
}
}
return new Vector2(0, 0);
}
int DetermineSize() {
Vector2 startPoint = FindFirstOpenCell(currentGrid);
List<Vector2> openCells = new List<Vector2>();
List<Vector2> tempList = new List<Vector2>();
openCells.Add(startPoint);
for (int o = 0; o < openCells.Count; o++) {
tempList.Clear();
tempList = GetOpenNeighborList((int)openCells[o].x, (int)openCells[o].y);
foreach(Vector2 item in tempList) {
if (!openCells.Contains(item)) {
openCells.Add(item);
}
}
}
return openCells.Count;
}
List<Vector2> GetOpenNeighborList(int x, int y) {
List<Vector2> openNeighbors = new List<Vector2>();
foreach (Vector2 offset in neighborOffsets) {
Vector2 neighborLoc = new Vector2(x + offset.x, y + offset.y);
if (!currentGrid[(int)neighborLoc.x, (int)neighborLoc.y]) {
openNeighbors.Add(new Vector2(x + offset.x, y + offset.y));
}
}
return openNeighbors;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment