Skip to content

Instantly share code, notes, and snippets.

@nzhul
Last active November 11, 2015 12:31
Show Gist options
  • Save nzhul/28f6070e7a879b0a4975 to your computer and use it in GitHub Desktop.
Save nzhul/28f6070e7a879b0a4975 to your computer and use it in GitHub Desktop.
Cellular automata - procedural cave generation
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);
}
}
}
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