Skip to content

Instantly share code, notes, and snippets.

@JonRurka
Last active August 29, 2015 14:12
Show Gist options
  • Save JonRurka/962b789113352a45a1e6 to your computer and use it in GitHub Desktop.
Save JonRurka/962b789113352a45a1e6 to your computer and use it in GitHub Desktop.
public class Maze
{
public enum Direction
{
N = 1,
W = 2
}
Stack s_stack;
Random rand;
public int MSIZEX;
public int MSIZEY;
public int[] maze_base;
public byte[,] maze_data;
private int iSmooth;
#region Generating
public void GenerateMaze(int sizeX, int sizeY, int seed, int smoothness)
{
iSmooth = smoothness;
MSIZEX = sizeX;
MSIZEY = sizeY;
maze_base = new int[MSIZEX * MSIZEY];
maze_data = new Byte[MSIZEX, MSIZEY];
s_stack = new Stack();
rand = new Random(seed);
MazeInit(rand);
cMazeState state = new cMazeState(rand.Next() % MSIZEX, rand.Next() % MSIZEY, 0);
analyze_cell(state, rand);
}
void analyze_cell(cMazeState s, Random r)
{
bool bEnd = false, found;
int indexSrc, indexDest, tDir = 0, prevDir = 0;
while (true)
{
if (s.dir == 15)
{
while (s.dir == 15)
{
s = (cMazeState)s_stack.pop();
if (s == null)
{
bEnd = true;
break;
}
}
if (bEnd == true) break;
}
else
{
do
{
prevDir = tDir;
tDir = (int)System.Math.Pow(2, r.Next() % 4);
if ((r.Next() % 32) < iSmooth)
if ((s.dir & prevDir) == 0)
tDir = prevDir;
if ((s.dir & tDir) != 0)
found = true;
else
found = false;
} while (found == true && s.dir != 15);
s.dir |= tDir;
indexSrc = cell_index(s.x, s.y);
// direction W
if (tDir == 1 && s.x > 0)
{
indexDest = cell_index(s.x - 1, s.y);
if (base_cell(indexSrc) != base_cell(indexDest))
{
merge(indexSrc, indexDest);
maze_data[s.x, s.y] |= (byte)Direction.W;
s_stack.push(new cMazeState(s));
s.x -= 1; s.dir = 0;
}
}
// direction E
if (tDir == 2 && s.x < MSIZEX - 1)
{
indexDest = cell_index(s.x + 1, s.y);
if (base_cell(indexSrc) != base_cell(indexDest))
{
merge(indexSrc, indexDest);
maze_data[s.x + 1, s.y] |= (byte)Direction.W;
s_stack.push(new cMazeState(s));
s.x += 1; s.dir = 0;
}
}
// direction N
if (tDir == 4 && s.y > 0)
{
indexDest = cell_index(s.x, s.y - 1);
if (base_cell(indexSrc) != base_cell(indexDest))
{
merge(indexSrc, indexDest);
maze_data[s.x, s.y] |= (byte)Direction.N;
s_stack.push(new cMazeState(s));
s.y -= 1; s.dir = 0;
}
}
// direction S
if (tDir == 8 && s.y < MSIZEY - 1)
{
indexDest = cell_index(s.x, s.y + 1);
if (base_cell(indexSrc) != base_cell(indexDest))
{
merge(indexSrc, indexDest);
maze_data[s.x, s.y + 1] |= (byte)Direction.N;
s_stack.push(new cMazeState(s));
s.y += 1; s.dir = 0;
}
}
} // else
} // while
} // function
#endregion
#region Bitmap
public Bitmap GetBitmap(int xS, int yS)
{
int i, j;
Bitmap tB = new Bitmap(xS + 1, yS + 1);
Graphics g = Graphics.FromImage((Image)tB);
Brush w = Brushes.White;
Brush b = Brushes.Black;
Pen bp = new Pen(b, 1);
// background
g.FillRectangle(w, 0, 0, tB.Width - 1, tB.Height - 1);
g.DrawRectangle(bp, 0, 0, tB.Width - 1, tB.Height - 1);
int xSize = xS / MSIZEX;
int ySize = yS / MSIZEY;
for (i = 0; i < MSIZEX; i++)
for (j = 0; j < MSIZEY; j++)
{
// inspect the maze
if ((maze_data[i, j] & (byte)Direction.N) == 0)
g.DrawLine(bp,
new Point(xSize * i, ySize * j),
new Point(xSize * (i + 1), ySize * j));
if ((maze_data[i, j] & (byte)Direction.W) == 0)
g.DrawLine(bp,
new Point(xSize * i, ySize * j),
new Point(xSize * i, ySize * (j + 1)));
}
// start & end
g.DrawLine(bp, 0, 0, xSize, 0);
g.DrawLine(bp, 0, 0, 0, xSize);
g.DrawLine(bp, xS, yS, xS - xSize, yS);
g.DrawLine(bp, xS, yS, xS, yS - ySize);
g.Dispose();
return tB;
}
#endregion
#region Cell functions
int cell_index(int x, int y)
{
return MSIZEX * y + x;
}
int base_cell(int tIndex)
{
int index = tIndex;
while (maze_base[index] >= 0)
{
index = maze_base[index];
}
return index;
}
void merge(int index1, int index2)
{
// merge both lists
int base1 = base_cell(index1);
int base2 = base_cell(index2);
maze_base[base2] = base1;
}
#endregion
#region MazeInit
void MazeInit(Random r)
{
int i, j;
// maze data
for (i = 0; i < MSIZEX; i++)
for (j = 0; j < MSIZEY; j++)
{
maze_base[cell_index(i, j)] = -1;
maze_data[i, j] = 0;
}
}
#endregion
}
ublic class cMazeState
{
public int x, y, dir;
public cMazeState(int tx, int ty, int td) { x = tx; y = ty; dir = td; }
public cMazeState(cMazeState s) { x = s.x; y = s.y; dir = s.dir; }
}
public class cCellPosition
{
public int x, y;
public cCellPosition() { }
public cCellPosition(int xp, int yp) { x = xp; y = yp; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment