Last active
November 11, 2015 12:31
-
-
Save nzhul/28f6070e7a879b0a4975 to your computer and use it in GitHub Desktop.
Cellular automata - procedural cave generation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace CellularAutomata | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
char key = new char(); | |
MapHandler Map = new MapHandler(); | |
string instructions = "[Q]uit [N]ew [+][-]Percent walls [R]andom [B]lank" + Environment.NewLine + | |
"Press any other key to smooth/step"; | |
Map.MakeCaverns(); | |
Map.PrintMap(); | |
key = Char.ToUpper(Console.ReadKey(true).KeyChar); | |
while (!key.Equals('Q')) | |
{ | |
if (key.Equals('+')) | |
{ | |
Map.PercentAreWalls += 1; | |
Map.RandomFillMap(); | |
Map.MakeCaverns(); | |
Map.PrintMap(); | |
} | |
else if (key.Equals('-')) | |
{ | |
Map.PercentAreWalls -= 1; | |
Map.RandomFillMap(); | |
Map.MakeCaverns(); | |
Map.PrintMap(); | |
} | |
else if (key.Equals('R')) | |
{ | |
Map.RandomFillMap(); | |
Map.PrintMap(); | |
} | |
else if (key.Equals('N')) | |
{ | |
Map.RandomFillMap(); | |
Map.MakeCaverns(); | |
Map.PrintMap(); | |
} | |
else if (key.Equals('B')) | |
{ | |
Map.BlankMap(); | |
Map.PrintMap(); | |
} | |
else if (key.Equals('D')) | |
{ | |
// Breakpoint here .. | |
} | |
else | |
{ | |
Map.MakeCaverns(); | |
Map.PrintMap(); | |
} | |
Console.WriteLine(instructions); | |
key = Char.ToUpper(Console.ReadKey(true).KeyChar); | |
} | |
Console.Clear(); | |
Console.Write(" END."); | |
Console.ReadKey(true); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
namespace CellularAutomata | |
{ | |
public class MapHandler | |
{ | |
Random rand = new Random(); | |
public int[,] Map; | |
public int MapWidth { get; set; } | |
public int MapHeight { get; set; } | |
public int PercentAreWalls { get; set; } | |
public MapHandler() | |
{ | |
MapWidth = 16; | |
MapHeight = 10; | |
PercentAreWalls = 40; | |
RandomFillMap(); | |
} | |
public void MakeCaverns() | |
{ | |
for (int column = 0, row = 0; row <= MapHeight - 1; row++) | |
{ | |
for (column = 0; column <= MapWidth - 1; column++) | |
{ | |
Map[column, row] = PlaceWallLogic(column, row); | |
} | |
} | |
} | |
public int PlaceWallLogic(int x, int y) | |
{ | |
int numWalls = GetAdjacentWalls(x, y, 1, 1); | |
if (Map[x, y] == 1) | |
{ | |
if (numWalls >= 4) | |
{ | |
return 1; | |
} | |
return 0; | |
} | |
else | |
{ | |
if (numWalls >= 5) | |
{ | |
return 1; | |
} | |
} | |
return 0; | |
} | |
private int GetAdjacentWalls(int x, int y, int scopeX, int scopeY) | |
{ | |
int startX = x - scopeX; | |
int startY = y - scopeY; | |
int endX = x + scopeX; | |
int endY = y + scopeY; | |
int iX = startX; | |
int iY = startY; | |
int wallCounter = 0; | |
for (iY = startY; iY <= endY; iY++) | |
{ | |
for (iX = startX; iX <= endX; iX++) | |
{ | |
if (!(iX == x && iY == y)) | |
{ | |
if (IsWall(iX, iY)) | |
{ | |
wallCounter += 1; | |
} | |
} | |
} | |
} | |
return wallCounter; | |
} | |
bool IsWall(int x, int y) | |
{ | |
if (IsOutOfBounds(x, y)) | |
{ | |
return true; | |
} | |
if (Map[x, y] == 1) | |
{ | |
return true; | |
} | |
if (Map[x, y] == 0) | |
{ | |
return false; | |
} | |
return false; | |
} | |
private bool IsOutOfBounds(int x, int y) | |
{ | |
if (x < 0 || y < 0 || x > MapWidth - 1 || y > MapHeight - 1) | |
{ | |
return true; | |
} | |
return false; | |
} | |
public void PrintMap() | |
{ | |
Console.Clear(); | |
Console.Write(MapToString()); | |
} | |
string MapToString() | |
{ | |
string returnString = string.Join(" ", | |
"Width:", | |
MapWidth.ToString(), | |
"\tHeight:", | |
MapHeight.ToString(), | |
"\t% Walls:", | |
PercentAreWalls.ToString(), | |
Environment.NewLine); | |
List<string> mapSymbols = new List<string>(); | |
mapSymbols.Add("."); | |
mapSymbols.Add("#"); | |
mapSymbols.Add("+"); | |
for (int row = 0; row < MapHeight; row++) | |
{ | |
for (int col = 0; col < MapWidth; col++) | |
{ | |
returnString += mapSymbols[Map[col, row]]; | |
} | |
returnString += Environment.NewLine; | |
} | |
return returnString; | |
} | |
public void BlankMap() | |
{ | |
for (int row = 0; row < MapHeight; row++) | |
{ | |
for (int col = 0; col < MapWidth; col++) | |
{ | |
Map[col, row] = 0; | |
} | |
} | |
} | |
public void RandomFillMap() | |
{ | |
// New, empty map | |
Map = new int[MapWidth, MapHeight]; | |
int mapMiddle = 0; // Temp variable | |
for (int column = 0, row = 0; row < MapHeight; row++) | |
{ | |
for (column = 0; column < MapWidth; column++) | |
{ | |
// If coordinants lie on the edge of the map | |
// (creates a border) | |
if (column == 0) | |
{ | |
Map[column, row] = 1; | |
} | |
else if (row == 0) | |
{ | |
Map[column, row] = 1; | |
} | |
else if (column == MapWidth - 1) | |
{ | |
Map[column, row] = 1; | |
} | |
else if (row == MapHeight - 1) | |
{ | |
Map[column, row] = 1; | |
} | |
// Else, fill with a wall a random percent of the time | |
else | |
{ | |
mapMiddle = (MapHeight / 2); | |
if (row == mapMiddle) | |
{ | |
Map[column, row] = 0; | |
} | |
else | |
{ | |
Map[column, row] = RandomPercent(PercentAreWalls); | |
} | |
} | |
} | |
} | |
} | |
int RandomPercent(int percent) | |
{ | |
if (percent >= rand.Next(1, 101)) | |
{ | |
return 1; | |
} | |
return 0; | |
} | |
public MapHandler(int mapWidth, int mapHeight, int[,] map, int percentWalls = 40) | |
{ | |
this.MapWidth = MapWidth; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment